简体   繁体   English

Python类特定的全局属性

[英]Python class specific global attributes

Lets say I have class SuperModel , Model , and SubModel . 假设我有类SuperModelModelSubModel

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM