【发布时间】:2014-05-31 18:44:48
【问题描述】:
如果我创建一个对象:
class eggs(object):
""" This wasn't needed """
def __setattr__(self, name, value):
print name, value
如果我这样做,我可以理解:
class eggs(object):
""" This wasn't needed """
def __setattr__(self, name, value):
print name, value
if __name__ == "__main__":
foo = eggs()
foo.bar = 5
print foo
我明白了:
bar 5
<__main__.eggs object at 0x8f8bb0c>
但是当我这样做时:
if __name__ == "__main__":
foo = eggs()
foo = 5
print foo
我明白了:
5
我的问题是调用foo = 5 时调用了什么“魔法”方法?
例如我这样做:
class eggs(object):
""" This wasn't needed """
def __init__(self):
self.bacon = False
def __setattr__(self, name, value):
if not name == "bacon":
raise Exception("No way Hosay")
if value not in [True, False]:
raise Exception("It wasn't supposed to be like this")
super(eggs, self).__setattr__(name, value)
print "Variable became {0}".format(value)
if __name__ == "__main__":
foo = eggs()
foo.bacon = True
foo.bacon = 5 > 4
foo.bacon = True or False
# ETC
返回:
Variable became False
Variable became True
Variable became True
Variable became True
我想不吃培根。
【问题讨论】:
-
你不只是重新分配变量吗?您不再设置
foo的属性,而是赋予foo一个全新的值,完全不同的类型。在你这样做之后,它甚至不属于eggs。没有什么神奇的方法,只是基本的编程逻辑。 -
我正在重新分配变量,但我想要一个在您尝试更改它时执行某些操作的对象?如果这有意义吗?我觉得它应该是可行的,但我认为它是错误的。
-
那是不可能的。赋值运算符重新绑定名称;它不会让以前绑定到该名称的对象做任何事情(嗯,除了间接地,通过减少其引用计数并因此可能调用其
__del__方法)。 -
@Noelkd 你来自 C++ 背景,对吧?在大多数语言(包括 Python)中,变量和对象是不同的,赋值适用于变量而不是变量引用的对象。 C++ 有点离群 - 对象类型的 C++ 变量实际上“包含”对象而不是引用它,
operator=是对象接口的一部分。 -
“魔法”方法被称为
__get__和__set__,但事情并不能完全按照您的意愿工作。请参阅有关描述符的 Python 文档
标签: python python-2.7 object variable-assignment