如何在\uyu init中定义属性__

2024-10-01 17:29:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我希望从成员函数定义类中的属性。 下面是一些测试代码,显示了我希望这是如何工作的。但是我没有得到预期的行为。在

class Basket(object):

  def __init__(self):
    # add all the properties
    for p in self.PropNames():
      setattr(self, p, property(lambda : p) )

  def PropNames(self):
    # The names of all the properties
    return ['Apple', 'Pear']

  # normal property
  Air = property(lambda s : "Air")

if __name__ == "__main__":
  b = Basket()
  print b.Air # outputs: "Air"
  print b.Apple # outputs: <property object at 0x...> 
  print b.Pear # outputs: <property object at 0x...> 

我怎么能让它工作?在


Tags: thelambdaselfappleobjectdefpropertyproperties
3条回答

您需要在类(即:self.__class__)上设置属性,而不是在对象(即:self)上设置属性。例如:

class Basket(object):

  def __init__(self):
    # add all the properties
    setattr(self.__class__, 'Apple', property(lambda s : 'Apple') )
    setattr(self.__class__, 'Pear', property(lambda s : 'Pear') )

  # normal property
  Air = property(lambda s : "Air")

if __name__ == "__main__":
  b = Basket()
  print b.Air # outputs: "Air"
  print b.Apple # outputs: "Apple"
  print b.Pear # outputs: "Pear"

值得一提的是,在循环中创建lamdas时使用p并没有给出您预期的行为。由于p的值是在循环过程中更改的,所以在循环中设置的两个属性都返回相同的值:p的最后一个值。在

这是你想要的:

class Basket(object):
  def __init__(self):
    # add all the properties

    def make_prop( name ):
        def getter( self ):
            return "I'm a " + name
        return property(getter)

    for p in self.PropNames():
        setattr(Basket, p, make_prop(p) )

  def PropNames(self):
    # The names of all the properties
    return ['Apple', 'Pear', 'Bread']

  # normal property
  Air = property(lambda s : "I'm Air")

if __name__ == "__main__":
  b = Basket()
  print b.Air 
  print b.Apple 
  print b.Pear 

另一种方法是元类。。。但是他们让很多人困惑。在

因为我无聊:

^{pr2}$

为什么要在__init__时间定义属性?这既令人困惑又聪明,所以你最好有一个很好的理由。Stef指出的循环问题只是为什么要避免这种情况的一个例子。在

如果需要重新定义子类具有哪些属性,可以在子类__init__方法中执行del self.<property name>,或者在子类中定义新属性。在

此外,一些风格挑剔:

  • 缩进到4个空格,而不是2个空格
  • 不要不必要地混合引用类型
  • 方法名使用下划线而不是大小写。PropNames->;prop_names
  • PropNames实际上并不需要是一种方法

相关问题 更多 >

    热门问题