有什么区别 __get__()
和 __getattr__()
在Python?我来自PHP背景,只有 __get()
。我什么时候应该使用哪个功能?
我一直试图解决这个问题。我看到很多问题 这个,询问之间的区别 __getattr__()
和 __getattribute__()
但是。
有什么区别 __get__()
和 __getattr__()
在Python?我来自PHP背景,只有 __get()
。我什么时候应该使用哪个功能?
我一直试图解决这个问题。我看到很多问题 这个,询问之间的区别 __getattr__()
和 __getattribute__()
但是。
您将找到所有这些方法的详细文档 这里。
来自PHP,您应该首先熟悉Python对象模型。它比PHP更丰富,所以你不应该尝试将你的PHP知识1:1映射到Python。如果要开发PHP,请使用PHP。如果你想用Python开发,学习Python。
回到原来的问题: __getattr__
可能是与...相同的功能 __get
PHP中的函数。 __get__
在Python中用于实现描述符。有关描述符的详细信息也可以在我上面提到的文档中找到。
您将找到所有这些方法的详细文档 这里。
来自PHP,您应该首先熟悉Python对象模型。它比PHP更丰富,所以你不应该尝试将你的PHP知识1:1映射到Python。如果要开发PHP,请使用PHP。如果你想用Python开发,学习Python。
回到原来的问题: __getattr__
可能是与...相同的功能 __get
PHP中的函数。 __get__
在Python中用于实现描述符。有关描述符的详细信息也可以在我上面提到的文档中找到。
首先,PHP确实如此 不 有一个相当于Python的 __get__()
- 差远了!你最需要的是什么 __getattr__()
。
我来自PHP背景,只有
__get__
PHP 有一个 神奇的方法 叫 __get()
,只要您尝试访问不存在的属性,就会调用它。
首先,让我们清楚一些事情:
__get__()
__getattr__()
__getattribute__()
__get()
(并分别针对所有setter方法。)
与Achim的假设相反, __get()
不 不 和Python一样 __getattr__()
!
Python不区分方法和属性,但PHP确实如此,这就是PHP有第二种方法的原因: __call()
。
__call()
每当您尝试在不存在的对象上调用方法时执行。 Python没有相应的,因为一个方法只是一个可调用的对象(属性)。
PHP中的一个例子:
<?php
$obj = new stdClass();
($obj->test)();
在Python中,这将失败 AttributeError
。但是,在PHP中,这样做 甚至没有编译:
解析错误:语法错误,意外'('第4行
与Python比较:
obj.method()
# is eqvuivalent to:
(obj.method)()
这是一个重要的区别。我们得出结论,PHP和Python思考调用方法的方式完全不同。
obj
知道 你称之为方法
obj
不 不。这使得PHP可以拥有 obj.does_not_exist
评估 3
但是 obj.does_not_exist()
至 5
。
据我所知,在Python中不可能这样做。 (这将允许我们将PHP的不一致性描述为一项功能。)
因此,我们将一个子弹点扩展到“不等效”列表:
__call()
/__callStatic()
PHP提供了两种不同的机制:
__get()
对于不存在的属性__call()
用于调用不存在的方法Python只有一种机制,因为它不区分属性和方法,只要它涉及它们都是属性。
__getattr__()
当属性不存在时调用。obj.non_existing()
不是特殊的“调用语法”,它是调用运算符的表达式 ()
被申请;被应用: (obj.__getattr__("non_existing"))()
放弃: __getattr__()
当属性不存在时,并不总是调用。 __getattribute__()
在查找链中具有最高优先级,因此可能导致 __getattr__()
被忽略
__get__()
Python中的内容与上面提到的完全不同。
该文档描述了描述符 "a descriptor is an object attribute with “binding behavior”"
。我可以直接理解“绑定行为”应该是什么意思,但仅仅因为我已经理解了描述符的作用。
我会选择将描述符描述为“自我意识 属性“可以在多个类之间共享。
让我解释一下,我的意思是“自我意识”。这样的属性:
这些属性是独立的对象:“描述符”对象,即遵循所谓的对象 “描述符协议”,它定义了一组方法及其对应的签名,这些对象可以实现。
对象不拥有描述符属性。实际上,它们属于对象的对应类(或其祖先)。但是,相同的描述符对象可以“属于”多个类。
注意:“通过他们阅读的人”,提及的正确方法是什么 obj
在 obj.attr
?我会说: attr
访问“通过” obj
。