[英]Python class specific global attributes
Lets say I have class SuperModel
, Model
, and SubModel
. 假设我有类
SuperModel
, Model
和SubModel
。
I want to define a global attribute 'collection' that is the name of the class. 我想定义一个全局属性'collection',它是该类的名称。 For example, If I do:
例如,如果我这样做:
Model.collection
it will return 'Model'. 它将返回'模型'。
If I subclass Model, say class SubModel(Model)
如果我是Model的子类,请说
class SubModel(Model)
Submodel.collection
will return 'Submodel' 将返回'Submodel'
Is there a way to do so without explicitly rewriting the attribute for all the descendants of Model? 有没有办法在没有明确重写Model的所有后代的属性的情况下这样做?
I was trying to get something out of metaclasses: 我试图从元类中获取一些东西:
class SuperModel(type):
def __new__(cls, name, base, attrs):
if 'collection' not in attrs:
attrs['collection'] = __name__.lower()
return super().__new__(cls, name, base, attrs)
class Model(metaclass=SuperModel):
pass
but when I try to subclass Model (for example class SubModel(Model)
) I always get 'Model' when printing 'collection' when I'm expecting 'SubModel'. 但是当我尝试子类Model(例如
class SubModel(Model)
)时,当我期待'SubModel'时,我总是在打印'collection'时得到'Model'。
Edit: I know there is a __name__
attribute but what if I wanted to assign the __name__
to a class variable each time the class is defined? 编辑:我知道有
__name__
属性但是如果我想在每次定义类时将__name__
分配给类变量怎么办? So when subclassing Model there would be an attribute 'collection' in SubModel that equals __name__
('SubModel'). 所以当子类化Model时,SubModel中会有一个等于
__name__
('SubModel')的属性'collection'。
There already is such an attribute built in, and it is called __name__
. 已经内置了这样的属性,它被称为
__name__
。
>>> class Foo(object):
... pass
>>> Foo.__name__
'Foo'
You are using the module global __name__
in your metaclass. 您在元类中使用模块global
__name__
。 That's neither the name of your metatype nor your class. 这既不是你的元型名称也不是你的类。
Your metaclass is handed the name of the new class already, in the name
attribute. 您的元类已经在
name
属性中传递了新类的name
。 Simply use that: 只需使用:
class SuperModel(type):
def __new__(cls, name, base, attrs):
if 'collection' not in attrs:
attrs['collection'] = name.lower()
return super().__new__(cls, name, base, attrs)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.