――Ich habe nachgeschlagen, was mein Kollege angekündigt hatte, und habe es für mich selbst nachgeschlagen und notiert.
class Person:
    name = 'takanory'
    
Person.name # => takanory
p1 = Person()
p1.name # => takanory
assert Person.name is p1.name  # same object
class Person(models.Model):
    name = models.CharField(max_length=255, default='takanory')
    age = 37
#Gewöhnliche Klassenvariablen existieren
Person.age # => 37
    
#Die Klassenvariable "Name" des Feldobjekts fehlt
Person.name 
# => AttributeError: type object 'Person' has no attribute 'name'
#Eigentlich ist "Name" "_meta.Existiert in "Feldern"
Person._meta.fields
# => (<django.db.models.fields.AutoField: id>, <django.db.models.fields.CharField: name>)
»Kein Wunder für diejenigen, die normalerweise Django verwenden
――Um diese Frage zu beantworten, müssen wir über Metaklassen sprechen. -Sie können ein Klassenobjekt mit dem Typ ** erstellen ** --Klassendefinition ist gleichbedeutend mit dem Erstellen eines Klassenobjekts mit dem Typ **
#Gewöhnliche Klassendefinition
class Person:
    name = 'takanory'
#Erstellen Sie dasselbe Klassenobjekt "Person" wie die obige Klassendefinition
Person = type('Person', tuple(), {'name': 'takanory'})
#Das Klassenobjekt ist eine Instanz vom Typ
assert isinstance(Person, type)
class Taka22(type):
    """ 
Name ist'takanory'Nur im Fall von
    nickname = 'taka22'Meta-Klasse zum Hinzufügen einer Klassenvariablen namens
    """
    def __new__(cls, name, bases, attrs):
        if attrs.get('name') == 'takanory':
            attrs['nickname'] = 'taka22'
        return super().__new__(cls, name, bases, attrs)  
class Person(metaclass=Taka22):
    name = 'takanory'
 
Person.nickname # => 'taka22'
―― An diesem Punkt können Sie sich vorstellen, dass die Metaklasse das "Feld verschwindet" aus der Klasse ausführt. --Überprüfen Sie tatsächlich das entsprechende Teil.
class Model(six.with_metaclass(ModelBase)):
    _deferred = False
    def __init__(self, *args, **kwargs):
# refs https://github.com/django/django/blob/master/django/db/models/base.py#L355
# python3
class Hoge(metaclass=NewMeta):
# python2
class Hoge(object):
    __metaclass__ = NewMeta
# python3 and python2
class Hoge(six.with_metaclass(NewMeta):
class ModelBase(type):
    """
    Metaclass for all models.
    """
    def __new__(cls, name, bases, attrs):
        #Übergeordnete Klasse(type)von__new__Methode
        super_new = super(ModelBase, cls).__new__
        # ~Kürzung~
        # Create the class.
        module = attrs.pop('__module__')
        #Nur Modul als attr und neu übergeben_Klasse generieren
        #Zu diesem Zeitpunkt sind die Klassenvariablen verschwunden
        new_class = super_new(cls, name, bases, {'__module__': module})
# refs https://github.com/django/django/blob/master/django/db/models/base.py#L67             
def add_to_class(cls, name, value):
    # We should call the contribute_to_class method only if it's bound
    if not inspect.isclass(value) and hasattr(value, 'contribute_to_class'):
        value.contribute_to_class(cls, name) #Wert ist ein Feldobjekt
    else:
        # contribute_to_Ich habe keine Klasse
        #attr wird wie in der Klassendefinition festgelegt(Zurück)
        setattr(cls, name, value)
# refs https://github.com/django/django/blob/c339a5a6f72690cd90d5a653dc108fbb60274a20/django/db/models/base.py#L303
def contribute_to_class(self, cls, name, private_only=False, virtual_only=NOT_PROVIDED):
    # ~Kürzung
    #Über diesen Bereich erhielt ich cls(=model)von_Ich füge mich als Felder zu Meta hinzu.
    self.model = cls
    if private_only:
        cls._meta.add_field(self, private=True)
    else:
        cls._meta.add_field(self)
    if self.choices:
        setattr(cls, 'get_%s_display' % self.name,
                    curry(cls._get_FIELD_display, field=self))
# refs https://github.com/django/django/blob/master/django/db/models/fields/__init__.py#L678
--Wie verschwinden Klassenvariablen wie Felder aus Djangos Modell?
class Person(models.Model):
    name = models.CharField(max_length=255, default='takanory')
    
p1 = Person()
p1.name # => 'takanory'
#Die Instanz kann direkt auf die Wertzeichenfolge "takanory" verweisen.
#Wenn das Personenmodell instanziiert, selbst.Der "Wert" des Feldes wird dem Namen zugewiesen
#Gleichzeitig wird die Klassenvariable "Person."Name" ist "Selbst".Kann nicht mit "Name" referenziert werden
#Deshalb "Person._meta.Wird es nicht zu "Feldern" evakuiert??
Recommended Posts