Python _uuugetAttribute_uuu如何获取值?
我试图理解Python _uuugetAttribute_uuu如何获取值?,python,python-3.x,function,class,built-in,Python,Python 3.x,Function,Class,Built In,我试图理解\uuu getattribute\uuu的底层机制。我理解(希望如此)super()。\uuuu getattribute\uuuu(value)在这种情况下会接触到对象类。但是object如何从test()类中提取name值呢?如果自己在类中进行编码而避免递归,那么如何使用\uuu getattribute\uuuu获取属性值 正如我所说,我想了解潜在的机制,我知道这不是你通常处理事情的方式 谢谢 不能用Python编写此代码。Python调用的是一个C函数: class test
\uuu getattribute\uuu
的底层机制。我理解(希望如此)super()。\uuuu getattribute\uuuu(value)
在这种情况下会接触到对象类。但是object
如何从test()类中提取name
值呢?如果自己在类中进行编码而避免递归,那么如何使用\uuu getattribute\uuuu
获取属性值
正如我所说,我想了解潜在的机制,我知道这不是你通常处理事情的方式
谢谢 不能用Python编写此代码。Python调用的是一个C函数:
class test():
name = 'arthur'
def __getattribute__(self, value):
return super().__getattribute__(value)
x = test()
x.name
------------------------------------------
Output: 'arthur'
这是
对象。\uuuu getattribute\uuuu
。在您的示例中调用它是因为所有类都继承自对象
首先,\uuu getattribute\uuuu
是一种神奇的方法(也称为dunder
方法/双下划线方法)。这是一个属性/属性访问器方法,它会在每次属性/属性访问时拦截,即使该属性/属性在类本身中可用。另一方面,只有在类/实例中不存在您正在访问的属性时,才会调用\uuu getattr\uuu
魔术方法。无论如何
还有一件更重要的事情需要注意,正如您可能已经知道的那样,所有类都隐式或显式地扩展/继承了基对象
类。因此,您定义的任何类,默认父类都是内置的对象
类。你问的时候很困惑:
我(希望)理解super()
在这种情况下,输出到对象
类。但是对象实际上是怎样的呢
从test()
类中提取name
值
让我们先看一些基本的例子:
PyObject *
PyObject_GetAttr(PyObject *v, PyObject *name)
{
PyTypeObject *tp = Py_TYPE(v);
if (!PyUnicode_Check(name)) {
PyErr_Format(PyExc_TypeError,
"attribute name must be string, not '%.200s'",
name->ob_type->tp_name);
return NULL;
}
if (tp->tp_getattro != NULL)
return (*tp->tp_getattro)(v, name);
if (tp->tp_getattr != NULL) {
const char *name_str = PyUnicode_AsUTF8(name);
if (name_str == NULL)
return NULL;
return (*tp->tp_getattr)(v, (char *)name_str);
}
PyErr_Format(PyExc_AttributeError,
"'%.50s' object has no attribute '%U'",
tp->tp_name, name);
return NULL;
}
相当于
class Foo:
def __init__(self, name):
self.name = name
def __getattribute__(self, name):
return super().__getattribute__(name)
那么,当你打电话的时候
class Foo(object):
def __init__(self, name):
self.name = name
def __getattribute__(self, name):
return object.__getattribute__(self, name)
您正在将上下文(类的实例)显式地传递给父(object
)类。因此父/对象类知道上下文并从传递的实例获取属性。另一方面,当你打电话时:
object.__getattribute__(self, name)
Python为您设置上下文。所以,你可以想象这样的情况:
super().__getattribute__(name)
但是在本例中,它是隐式的,super()
调用知道在哪里查找属性。值得一提的是,Python的super()
内置函数返回一个代理,一个替代对象,可以通过委托调用基类的方法,并且super()
可以接受两个参数(正如您在前面的代码片段中看到的),第一个是子类类型(在本例中为test
),第二个参数是一个对象,一个子类(test
)的实例
在python3
中,super(test,self)
调用相当于无参数的super()
调用。希望我已经澄清了你的困惑。您可以阅读更多信息。我以前读过这篇文章,没有任何答案回答我的具体问题,但无论如何,谢谢您。因此,为了确保我正确理解它,当super()\uuu getattribute\uu(value)
到达对象时,对象调用名为builtin\u getatrr
的内部C函数,该函数通过继承搜索来搜索所需的值,同时以某种方式避免再次触发\uuu getattribute\uuuu
?(我不懂C代码,这就是我问的原因)@Arthred更新。最后一个代码是为getattr
编写的,这可能就是它令人困惑的原因。非常感谢!我需要了解如何object.\uuuuu getattribute.\uuuuuu
避免陷入递归循环并实际获取所需的值吗?因为直到现在,在我读到的所有地方,我们都需要调用object.\uu getattribute
因为否则我们会陷入循环,我很想知道object实际上是如何避免的that@Arthred 不客气。您使用的是super()
,它是object
而不是test
。没有递归。
super(test, self).__getattribute__(name) # it's valid