Python 如何在u_init中定义属性__
我希望通过成员函数在类中定义属性。 下面是一些测试代码,显示了我希望它如何工作。然而,我没有得到预期的行为Python 如何在u_init中定义属性__,python,properties,constructor,Python,Properties,Constructor,我希望通过成员函数在类中定义属性。 下面是一些测试代码,显示了我希望它如何工作。然而,我没有得到预期的行为 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 al
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...>
类篮(对象):
定义初始化(自):
#添加所有属性
对于self.PropNames()中的p:
setattr(self,p,property(lambda:p))
def PropNames(自身):
#所有属性的名称
return['Apple'、'Pear']
#正常性质
空气=财产(λs:“空气”)
如果名称=“\uuuuu main\uuuuuuuu”:
b=篮子()
打印b.空气#输出:“空气”
打印b.苹果#输出:
打印b.Pear#输出:
我如何才能让它工作?您需要在类(即:
self.\uuuuu class\uuuuu
)上设置属性,而不是在对象(即: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
另一种方法是元类。。。但是他们让很多人困惑
因为我很无聊:
class WithProperties(type):
""" Converts `__props__` names to actual properties """
def __new__(cls, name, bases, attrs):
props = set( attrs.get('__props__', () ) )
for base in bases:
props |= set( getattr( base, '__props__', () ) )
def make_prop( name ):
def getter( self ):
return "I'm a " + name
return property( getter )
for prop in props:
attrs[ prop ] = make_prop( prop )
return super(WithProperties, cls).__new__(cls, name, bases, attrs)
class Basket(object):
__metaclass__ = WithProperties
__props__ = ['Apple', 'Pear']
Air = property(lambda s : "I'm Air")
class OtherBasket(Basket):
__props__ = ['Fish', 'Bread']
if __name__ == "__main__":
b = Basket()
print b.Air
print b.Apple
print b.Pear
c = OtherBasket()
print c.Air
print c.Apple
print c.Pear
print c.Fish
print c.Bread
为什么要在
\uuuu init\uuuu
时间定义属性?这很令人困惑,也很聪明,所以你最好有一个很好的理由。Stef指出的循环问题只是应该避免这种情况的一个例子
如果您需要重新定义子类具有哪些属性,您可以在子类\uuuu init\uuuu
方法中执行del self.
,或者在子类中定义新属性
此外,还有一些风格上的挑剔:
- 缩进到4个空格,而不是2个空格
- 不要不必要地混合报价类型
- 方法名称使用下划线而不是驼峰大小写<代码>道具名称->
道具名称
实际上不需要是一种方法PropNames