Python - 传递对象值而不是引用

标签 python python-2.7 reference

在 Python 中,据我所知,变量实际上是对给定命名空间中对象的引用。所以在下面的例子中,不足为奇的是,当全局命名空间中的noise发生变化时,cat.noise返回的值也会发生变化,因为setattr中的引用 行使用的是 noisereference,而不是其基础值。

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 时传递噪音的 value ?我认为我可以通过使用一个函数来隔离 namespace ,并且确实有效:

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 等)?作为次要问题,我对引擎盖下发生的事情的推理是否正确?

编辑

根据评论中对不那么做作的示例的请求,请考虑以下内容。假设我正在尝试根据它的 friend Dog 的值动态设置 Cat 中的属性:

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

最佳答案

只需将噪声值传递给setattr 函数即可。例如

class C(object):
    pass


noise = 'mrrrr'

setattr(C, 'noise', noise)

c = C()

c.noise
# outputs 'mrrrr'

noise = 'qwe'

c.noise
# outputs 'mrrrr'

编辑:用于出于某种原因需要 getter 函数的情况。

您可以使用中间值。

class D(object):
    pass


 noise = 'mrrrr'

 setattr(D, '_noise', noise)

 setattr(D, 'noise', property(lambda self: self._noise))

 d = D()

 d.noise
 # Outputs 'mrrrr'

 noise = 'pheew'

 d.noise
 # Outputs 'mrrrr'

编辑 2:使用偏函数。

import functools

class E(object):
    pass


noise = 'mrrrr'

getter = lambda _, noise: noise

partial = functools.partial(getter, noise=noise)

setattr(E, 'noise', property(partial))

e = E()

e.noise
# Outputs 'mrrrr'

noise = 'fooooo'

e.noise
# Outputs 'mrrrr'

关于Python - 传递对象值而不是引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40664893/

相关文章:

python - 用 python 填充 excel 文件搞乱了我的日期

python-2.7 - 父树 : Expected a node value and child list or a single string or 'ParentedTree' object has no attribute 'label'

python - 如果Python切片复制引用,为什么我不能用它来修改原始列表?

python-2.7 - 没有名为 urllib3 的模块 - 尝试安装 pip

c++ - 使用 g++ 的成员函数的 undefined reference

excel - 如何制作自定义填充 handle 图案?

python - 负向求Python

python - 如何 'index' 命名元组

python - 从 MATLAB 调用 Python 运算符错误 x**2

python - 如何旋转数据框?