添加类属性在Python

问题描述:

使用for循环,我试图从字典生成类:添加类属性在Python

class attr: 
    for key in objects_type: 
     setattr(attr, key, lambda cl: list()) 

这给attr属性没有在for循环中定义的错误。我知道我可以写:

class attr: 
    pass 
for key in objects_type: 
    setattr(attr, key, lambda cl: list()) 

但我相信我记得看到类似于第一个示例代码的某个地方。有谁知道是否有可能写出类似于第一种形式的东西?

尽管这不是很优雅,你可以使用locals()

>>> class c(object): 
...  for i in range(10): 
...   locals()['A' + str(i)] = i 
... 
>>> c.A0 
0 
>>> c.A7 
7 
+0

这一定是我记得看到的。感谢 – Casebash 2010-02-15 11:17:40

+0

事实上,我认为它比使用setattr更好 - 所以我不会说它不雅的 – Casebash 2010-02-15 11:19:13

+6

你不应该改变本地()字典:http://docs.python.org/library/functions .html#本地人 – stephan 2010-02-15 11:27:21

我不完全知道,你在做什么。我可以给你举个例子,在for循环中向类中添加类属性:

attributes = ('x', 5), ('y', 6), ('name', 'Cls') 

class Cls: 
    pass 
for key, value in attributes: 
    setattr(Cls, key, value) 

请记住,必须在定义整个类之后运行。你会得到错误,该attr没有定义,因为你想访问类之前你创建它class ...是在Python中,它创建一个类对象)的语句。创建类并记住之后,必须添加属性,这些属性将是类属性,而不是实例属性。

class Attr: 
    def __init__(self): 
    for key in objects_type: 
     setattr(Attr, key, lambda cl: list()) 
+1

+1:好。为什么不是从'object'继承的“新风格”类? – 2010-02-15 11:11:50

+2

这是做错的地方。它不仅浪费,而且现有的绑定方法将与稍后实例化的绑定方法不同。那么,比平常更多不同。 – 2010-02-15 11:13:13

newmeths = { 
    'two': lambda self: 2, 
} 

class MC(type): 
    def __init__(cls, name, bases, dict): 
    for k, v in newmeths.iteritems(): 
     setattr(cls, k, v) 
    super(MC, cls).__init__(name, bases, dict) 

class C(object): 
    __metaclass__ = MC 
    pass 

c=C() 
print c.two() 

假设你要动态地添加类属性,如这些

classDict = {} 
for i in range(2): 
    classDict["func%s"%(i+1)] = lambda self:"X" 

你可以这样做在几个方面,例如刚下课已经被创建之后,因为你can'y内轻松访问类的类名

class Attr2(object): 
    pass 

for n,v in classDict.iteritems(): 
    setattr(Attr2, n, v) 

print Attr2().func1(), Attr2().func2() 

或更好的只是动态创建类例如添加属性

Attr3 = type("Attr3",(), classDict) 
print Attr3().func1(), Attr3().func2() 

,或者如果你要使用元类e.g

class AttrMeta(type): 
    def __new__(cls, name, bases, dct): 
     dct.update(classDict) 
     return type.__new__(cls, name, bases, dct) 

class Attr4(object): 
    __metaclass__ = AttrMeta 

print Attr4().func1(), Attr4().func2() 
+1

我认为'type'方法是最好的解决方案,给出了这个问题。它确实要求程序员重新构造定义类属性的其余部分。另一方面,它避免了挖掘'locals()',避免定义一个自定义元类,并避免使用其他_other_元类的逻辑。国际海事组织,这使得它适合其他人将使用和贡献的图书馆。 – AlanSE 2017-11-01 21:52:20