Python非常动态的类属性

Python非常动态的类属性,python,class,Python,Class,要在类中创建属性,只需执行self.property=value。我想让这个类中的属性完全依赖于一个参数。让我们把这个类称为Foo Foo类的实例将包含一个元组列表: l = [("first","foo"),("second","bar"),("anything","you get the point")] bar = Foo(l) 现在,我们分配给bar的Foo类的实例将具有以下属性: bar.first #foo bar.second #bar bar.anything #you get

要在类中创建属性,只需执行
self.property=value
。我想让这个类中的属性完全依赖于一个参数。让我们把这个类称为Foo

Foo
类的实例将包含一个元组列表:

l = [("first","foo"),("second","bar"),("anything","you get the point")]
bar = Foo(l)
现在,我们分配给
bar
Foo
类的实例将具有以下属性:

bar.first
#foo
bar.second
#bar
bar.anything
#you get the point
这有可能吗?怎么做?

像这样的事情

>>> 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'
使用,您可以通过传入列表并在其中迭代来完成此操作。

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

class Foo(object):
    def __init__(self, l):
        for k, v in l:
            setattr(self, k, v)
这将获取
l
中的每个键值对,并将
Foo
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
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

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

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

    class Foo:
      def __init__(self, l):
        for (a, b) in l:
          setattr(self, a, b)
    
  • 定义自定义的
    \uuu getattr\uuu
    方法。最好将属性存储在
    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
    

    • 我想到了另一个你可以使用的答案。这与我当前的答案完全不同,因此我添加了一个不同的答案:

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

      type()
      返回的是一个类,而不是一个实例,因此在末尾有额外的
      ()

      请看。您可能还想看看。setattr工作得很好!谢谢我将研究namedtuple
      setattr(Foo…
      setattr有什么区别(self…
      ?我相信这是因为self是每个特定的类,而Foo是一般的类,所以它将使所有Foo类都有它。虽然不确定,但我只是speculating@Haidro:
      self
      为当前实例设置属性,而不是为
      class
      @Johnsyweb-Ah设置属性,因此使用
      self :).1在
      \uu getattr\uuu
      中,你需要有
      self.l
      ,而不是
      l
      ,这是非常有创意和压缩的…+1这很酷。昨天,我学会了用javascript和
      函数做同样的事情,今天我学会了用python做。OSM也是如此。@theourtheye:你甚至可以使用
      类型来动态构建函数nctionType
      。当然,您首先需要获得一个代码对象(通过编译一个、从另一个函数借用一个、手动生成字节码等等)。通常,在Python中有更好的方法来实现这一点……但您能想到的几乎任何事情都是可能的。