Digression Start
我刚学会了Python中的元类。我不认为python的创建者希望每个人都使用它们。我的意思是名字,在大多数情况下可能不是一个类的元类足以让大多数人远离这个概念!
Digression结束
关于我的问题。我编写了这个简单的元类来为模块中创建的所有类添加默认的文档字符串。但它不起作用:
def metest(cls,name,bases,dict):
cls.setattr(cls,'__doc__',"""Default Doc""")
return type(cls,(),{})
__metaclass__=metest
class test(object):
pass
print test.__doc__
t=test()
print t.__doc__
输出:
None
None
我做错了什么?
答案 0 :(得分:4)
我并不完全熟悉你正在做的全局方法,设置__metaclass__
就是这样。据我所知,它是另一种有效的风格。
但我会提供一个我熟悉的例子:
class MeTest(type):
def __new__(cls,name,bases,dict):
dict['__doc__'] = """Default Doc"""
return type.__new__(cls,name,bases,dict)
class Test(object):
__metaclass__ = MeTest
答案 1 :(得分:3)
我让你的例子工作:
def metest(name, bases, dict):
print name, bases, dict
dict['__doc__'] = """New Doc"""
cls = type(name+"_meta", bases, dict)
return cls
class Test(object):
"Old doc"
__metaclass__ = metest
print Test
print Test.__doc__
t = Test()
print t.__doc__
cls
将由我们创建。答案 2 :(得分:2)
请参阅此答案:Python metaclass and the object base class
提供object
基类会覆盖模块级元类,并将其替换为type
(object
的元类)。
此外,您的元类错误,即使您将其应用(通过在类中设置__metaclass__
)也无法工作。它应该只接受三个论点。您通常会看到接受四个的示例,但这是因为元类通常是猜测什么是类,所以它接受一个额外的“自我”参数(按惯例称为cls
元类)。
答案 3 :(得分:1)
这可能就是你想要的。从object
继承将使元类type
成为可能,因此如果要使用全局元类,则不能这样做
def metest(name, bases, dct):
dct['__doc__'] = """Default Doc"""
return type(name, bases, dct)
__metaclass__=metest
class test:
pass
print test.__doc__
t=test()
print t.__doc__
答案 4 :(得分:1)
您的模块级元类被覆盖,正如BrenBarn所述。 要解决此问题,请尝试将其编码为 return cls ,而不是将其设置为类实例。