在Python中,據我瞭解,變量實際上是對給定名稱空間中對象的引用。因此,在下面的示例中,當全局名稱空間中的noise
更改時,由cat.noise
返回的值會發生變化,因爲setattr
行中的引用使用的是noise
的引用,而不是其基礎值。Python - 傳遞對象值而不是引用
class Cat(object):
pass
noise = "meow"
setattr(Cat, "noise", property(lambda self: noise))
cat = Cat()
cat.noise
# Outputs "meow"
noise = "purrrrr"
cat.noise
# Outputs "purrrrr"
這就是說,有一個方法如上述主叫setattr
當傳遞值噪聲的?我想,我可以通過使用功能隔離的命名空間,並做了工作:
class Cat(object):
pass
noise = "meow"
def setproperties(cls, k, v):
setattr(cls, k, property(lambda self: v))
setproperties(Cat, "noise", noise)
cat = Cat()
cat.noise
# Outputs "meow"
noise = "purrrrr"
cat.noise
# Still outputs "meow"
是否有可能這樣做,而沒有經過對象通過函數(不使用eval
等)?作爲第二個問題,我的推理是否正確?
按照用於評價一個較少人爲的例子的要求,考慮以下。想象一下,我試圖在Cat
動態設置屬性,是根據它的朋友Dog
值:
class Dog(object):
noise = 'woof'
adorable = True
class Cat(object):
friend = Dog
friend_attrs = filter(lambda attr: not attr.startswith('__'), Dog.__dict__)
for attr in friend_attrs:
setattr(Cat, "friend_" + attr, property(lambda self: getattr(self.friend, attr)))
cat = Cat()
cat.friend_noise
# Outputs True
cat.friend_adorable
# Outputs True
你爲什麼要使用一個屬性,而不是直接的價值本身? – Evert
@Evert不幸的是,在我正在使用的現實世界中,它需要屬性,因爲lambda函數更復雜。我知道上面的例子有點人爲... – aensm
「它確實需要屬性,因爲lambda函數更復雜」 - 完全是什麼問題?你可以舉一個不太人爲的例子嗎? –