在Python中使用for循环添加类属性

时间:2010-02-15 10:58:56

标签: python metaprogramming

我试图从字典中生成一个类:

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

这给出了在for循环期间未定义attr的错误。我知道我可以写:

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

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

6 个答案:

答案 0 :(得分:6)

虽然不是很优雅,但您可以使用locals()

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

答案 1 :(得分:3)

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()

答案 2 :(得分:3)

假设您想要动态添加类属性,例如这些

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

你可以用几种方式做到这一点,例如只需在创建类后添加属性,因为您可以轻松访问类

中的类名
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()

或者如果您希望使用元类,例如

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()

答案 3 :(得分:2)

我不知道你在做什么。我可以举例说明在for循环中为类添加类属性:

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

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

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

答案 4 :(得分:1)

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

答案 5 :(得分:-1)

我为此苦苦思索了很长时间,最终还是通过一个示例解决了这个问题(因为我对编码很陌生):

names = ['Cuba I', 'San Felipe II Okeechobee', 'Bahamas', 'Cuba II', 'CubaBrownsville', 'Tampico', 'Labor Day', 
'New England', 'Carol', 'Janet', 'Carla', 'Hattie', 'Beulah', 'Camille', 'Edith', 'Anita', 'David', 'Allen', 
'Gilbert', 'Hugo', 'Andrew', 'Mitch', 'Isabel', 'Ivan', 'Emily', 'Katrina', 'Rita', 'Wilma', 'Dean', 'Felix', 
'Matthew', 'Irma', 'Maria', 'Michael']

for i in range(len(names)):
    namev                                      =                    names[i]
    locals()[''+str(namev.replace(' ',''))+''] =                  Hurricane(
        name                                   =                      namev)

因此,“飓风”类别下的“古巴I”将是“古巴I”。根据我对其他开发人员的研究,强烈建议不要这样做,因为我还不确定。似乎可以很好地应对当前的挑战。无论如何,它会做什么。