――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