Python非常动态的类属性

时间:2013-10-06 02:36:38

标签: python class

要在班级中创建属性,只需执行self.property = value即可。我希望能够让这个类中的属性完全依赖于参数。我们称这个班为Foo

Foo类的实例将采用元组列表:

l = [("first","foo"),("second","bar"),("anything","you get the point")]
bar = Foo(l)

现在我们分配给Foo的{​​{1}}类的实例将具有以下属性:

bar

这甚至是远程可能吗?怎么样?

5 个答案:

答案 0 :(得分:6)

我想到了使用type()可以使用的另一个答案。这与我目前的答案完全不同,所以我添加了一个不同的答案:

>>> bar = type('Foo', (), dict(l))()
>>> bar.first
'foo'
>>> bar.second
'bar'
>>> bar.anything
'you get the point'

type()会返回,而不是实例,因此最后会收到额外的()

答案 1 :(得分:4)

这些称为属性,而不是属性。考虑到这一点,方法setattr()变得更加明显:

class Foo(object):
    def __init__(self, l):
        for k, v in l:
            setattr(self, k, v)

这会获取l中的每个键值对,并将kFoo)的新实例上的属性self设置为v。< / p>

使用您的示例:

l = [("first","foo"),("second","bar"),("anything","you get the point")]
bar = Foo(l)

print bar.first
#foo
print bar.second
#bar
print bar.anything
#you get the point

答案 2 :(得分:3)

有两种方法可以做到这一点:

  • 像这样使用setattr。如果您只需要在构造对象时处理初始列表,这种方法是可行的。

    class Foo:
      def __init__(self, l):
        for (a, b) in l:
          setattr(self, a, b)
    
  • 定义自定义__getattr__方法。最好将属性存储在dict中以便更快地查找,但您也可以搜索原始列表。如果您想稍后修改列表并希望将其反映在对象的属性中,则效果会更好。

    class Foo:
      def __init__(self, l):
        self.l = l
      def __getattr__(self, name):
        for a in self.l:
          if a[0] == name:
            return a[1]
        return None
    

答案 3 :(得分:2)

这样的东西?

>>> class Foo:
...     def __init__(self, mylist):
...         for k, v in mylist:
...             setattr(self, k, v)
... 
>>> l = [("first","foo"),("second","bar"),("anything","you get the point")]
>>> bar = Foo(l)
>>> bar.first
'foo'
>>> bar.second
'bar'
>>> bar.anything
'you get the point'

使用setattr,您可以通过传入列表并迭代它来完成此操作。

答案 4 :(得分:-1)

setattr有效。

>>> class Foo:
...   def __init__(self,yahoo):
...     for k,v in yahoo:
...       setattr(self,k,v)
...
>>> l = [("first","foo"),("second","bar"),("anything","you get the point")]
>>> bar = Foo(l)
>>> print bar.first
foo
>>> print bar.second
bar
>>> print bar.anything
you get the point