在Python3中(从3.3版开始),最直接的方法是使用^{}(这是由于answer我遇到的):class Foo(object):
name = __qualname__
class Bar(Foo):
name = __qualname__
print((Foo.name, Bar.name))
这将产生所需的输出:
^{pr2}$
对于早期版本,或者如果你想更明确地说,你可以直接提到你的类的名称(是的,它不是干的,但它是KISS):class Foo(object):
name = Foo.__name__
class Bar(Foo):
name = Bar.__name__
print((Foo.name, Bar.name))
但是,上面的两个建议都要求您在派生类中重新分配名称。显然,当您在问题中实现了一个时,您意识到可以只使用一个类方法,但是每次需要名称时都必须调用它:class Foo(object):
@classmethod
def name(cls):
return cls.__name__
class Bar(Foo):
pass
print((Foo.name(), Bar.name()))
如果您不喜欢紧靠name的括号,那么您可能需要考虑创建一个类属性。这样就可以保持它的只读和可继承性,就像类方法方法一样,但仍然保持类变量的外观。创建类属性是this question的主题。其中一个answer建议使用方法修饰符(classproperty,在这里定义),尽管有些冗长(尽管可以删掉setter方法):# classproperty is defined in the aforementioned answer
class Foo(object):
@classproperty
def name(cls):
return cls.__name__
class Bar(Foo):
pass
print((Foo.name, Bar.name))
另一个answer建议使用元类。这对我来说是个新概念。虽然它提供了简洁的代码,但提姆·彼得斯(Tim Peters)mentioned in this pretty good guide about meta classes的引用阻止了我推荐它:class FooMetaclass(type):
@property
def name(cls):
return cls.__name__
class Foo(metaclass=FooMetaclass):
# for Python 2, remove the metaclass assignment above, and add:
# __metaclass__ = FeatureMetaclass
pass
class Bar(Foo):
pass
print((Foo.name, Bar.name))
我觉得这些就够了。:)