为啥从类和实例中获取属性的查找过程不同?

     2023-02-23     179

关键词:

【中文标题】为啥从类和实例中获取属性的查找过程不同?【英文标题】:Why are the lookup procedures for getting an attribute from a class and from an instance different?为什么从类和实例中获取属性的查找过程不同? 【发布时间】:2017-12-09 19:59:14 【问题描述】:

Python in a Nutshell 描述了获取属性时的查找过程。本书区分了两种情况

从类中获取属性时的查找过程,例如cls.name

从类中获取属性

当您使用语法C.name 来引用属性时 在类对象C 上,查找分两步进行:

    nameC.__dict__ 中的键时,C.nameC.__dict__['name'] 获取值 v。然后,当v 是 一个描述符(即type(v) 提供一个名为 __get__ ),C.name 的值是调用的结果 type(v).__get__(v, None, C) 。当v 不是描述符时, C.name is v 的值。

    name 不是 C.__dict__ 中的键时,C.name 将查找委托给 C 的基类,这意味着它在 C 的基类上循环 祖先类并尝试对每个类进行名称查找(在方法中 解决顺序,如页面上的“方法解决顺序”中所述 113).

the lookup procedure when getting an attribute from an instance, e.g. obj.name

由于在 Python 3 中,每个类对象实际上都是其元类的一个实例(例如type 类),根据本书,为什么从类中获取属性的查找过程和获取属性的查找过程是来自不同实例的属性?

【问题讨论】:

【参考方案1】:

它们并没有非常不同,书中的描述涵盖了它们不同的两种方式:

    在类实例上找到的描述符(在类上找不到之后)不会被调用(a.x = somedescriptor() 其中a 是类实例,而不是类,后面跟a.x 只会返回实例somedescriptor() 你刚刚创建的),而在元类实例上找到的描述符,即一个类(在元类上找不到之后)被调用,None 作为它被调用的实例(A.x = somedescriptor() 其中A 是元类实例,而不是元类,将在您刚刚创建的 somedescriptor() 上调用 .__get__(None, A))。这允许像 @classmethod 这样的东西通过将方法绑定到类本身来工作,无论它是在类的实例还是类本身上查找。 类实例没有“父实例”的概念(类实例本身的命名空间是一个平面dict,即使与该类实例关联的属性是由多个继承级别的方法定义的) ,因此基于 MRO 的查找的想法是元类实例所独有的。

其他一切都差不多,只是本书在这里掩盖了元类的概念,因为大多数类都是基类type 的实例,它没有特殊行为。如果您有type 以外的元类,则在查找类的属性时会应用完整的实例查找规则(只是该类的类是元类)。

他们可能在早期试图避免元类的复杂性,但在这个过程中,实例查找的规则似乎不适用于类;确实如此,只是类在基本查找过程中添加了一些额外的规则。

【讨论】:

谢谢!你的意思是从书中的类中获取属性的查找过程只有在类是type类的实例时才有效? 请问您对setting attribute的看法? @Tim:这意味着当它是type 的一个实例时,规则按照所写的方式应用,但是如果它有一些其他元类,则规则可以调用所有的行为“正常”实例。一个非常简单的元类最终可能表现得与type 相同(因为它是type 的子类,所以它根本不需要不同),一个更复杂的元类可能会定义所有使实例更复杂的古怪事物。 “它是type 的子类”,你的意思是“它是type 的一个实例”吗(我猜“它”的意思是“一个非常简单的元类”)?如果一个非常简单的元类与type 完全没有区别,那么使用非常简单的元类而不是直接使用type 作为元类的原因是什么? @Maggyero:啊,你是对的。我花了一点时间弄清楚你在说什么(我最初将其误读为关于在使用元类访问内容时未在元类上调用描述符协议的声明)。您不能让常规实例在每个实例属性上调用描述符协议(说a.x = property(somefunc) 不会让a.x 做任何事情,只会返回原始property 对象),但它会在每个类属性上发生元类不通过描述符提供覆盖。我会调整答案以涵盖这一点。

jQuery - 从类的元素中获取属性值的列表

】jQuery-从类的元素中获取属性值的列表【英文标题】:jQuery-getalistofvaluesofanattributefromelementsofaclass【发布时间】:2011-02-1418:58:35【问题描述】:我有一个类.object,它有一个名为level的属性。我想在页面上获取level的所有不同值的... 查看详情

在python中获取类和实例的属性

】在python中获取类和实例的属性【英文标题】:Getattributesforclassandinstanceinpython【发布时间】:2013-03-0112:32:48【问题描述】:在python中工作下一个代码:classMyClass(object):field=1>>>MyClass.field1>>>MyClass().field1当我想要自定... 查看详情

在 Python 中,为啥属性优先于实例属性?

】在Python中,为啥属性优先于实例属性?【英文标题】:InPython,whydopropertiestakepriorityoverinstanceattributes?在Python中,为什么属性优先于实例属性?【发布时间】:2019-05-1700:01:43【问题描述】:Thisarticle描述了Python在执行o.a时如何查... 查看详情

类和实例属性的查找顺序mro查找(代码片段)

如果多个类继承父类,然后又被多个类继承这种复杂的问题,可以使用mro方法例如:classA:passclassC(D):passclassB(D):passclassA(B,C):passprint(A.__mro__) python3主要使用的是C3算法,能够自适应深度查找和广度查找 查看详情

为啥静态绑定对类和函数的工作方式不同?

】为啥静态绑定对类和函数的工作方式不同?【英文标题】:Whystaticbindingworksdifferentlyforclassandfunction?为什么静态绑定对类和函数的工作方式不同?【发布时间】:2013-12-0712:48:33【问题描述】:在python中(在2.7.6上测试)所有变量... 查看详情

朴素贝叶斯 (Weka) - 属性总数 x 实例总数 - 为啥不同?

】朴素贝叶斯(Weka)-属性总数x实例总数-为啥不同?【英文标题】:NaiveBayes(Weka)-AttributestotalxInstancestotal-Whyisitdifferent?朴素贝叶斯(Weka)-属性总数x实例总数-为什么不同?【发布时间】:2013-11-0614:59:09【问题描述】:我一直在通过Weka... 查看详情

Javascript - 从数组中查找所有类,从类中获取并返回内部文本

】Javascript-从数组中查找所有类,从类中获取并返回内部文本【英文标题】:Javascript-findallclassesfromarray,grabandreturninnertextfromclasses【发布时间】:2013-11-2401:09:27【问题描述】:我有一组要在页面中搜索的类名。然后我想找到所有... 查看详情

如何从类模块中获取当前活动表单的属性?

】如何从类模块中获取当前活动表单的属性?【英文标题】:Howtogetthepropertiesofthecurrentactiveformfromaclassmodule?【发布时间】:2018-02-2007:36:08【问题描述】:我目前有2个表单,其中包含ListBox的记录和一些TextBox以允许用户输入。我有... 查看详情

10类和对象

1、实现一个手机类,并实例化你的手机。要求类里要有:属性+行为。至少应该具有品牌,型号等信息。拨打电话,发短信等功能。尽量多的获取不同属性和使用不同的功能。 2、 灰色的Tom猫,今年1岁,吃着美味的食物... 查看详情

什么类和对象

...;类是对象的模板,对象是类创建出的一个实例。   从类的作用来分析,类似对象的“模子”或“”原型,用于创建对象。使用类创建出的对象都具有类的属性和方法,每个对象的属性值可能不同。类的定义࿱... 查看详情

类对象

...界,有多种多样的类组成,多种类中又有不同的具体对象从类到对象  把类实例化===实例化一个对象===创建一个对象  赋值就是实例化的过程从对象到类  把实例抽象化===抽象化一个类===创建一个类  声明属性就是抽象... 查看详情

您可以从类中获取实例变量名称吗? [复制]

】您可以从类中获取实例变量名称吗?[复制]【英文标题】:Canyougettheinstancevariablenamefromaclass?[duplicate]【发布时间】:2015-08-2305:00:57【问题描述】:我知道你不应该在程序中使用变量名,但我使用的只是为了调试目的,并希望将... 查看详情

尝试在 Google 表格中使用 XML 从类的最后一个实例中获取数据

】尝试在Google表格中使用XML从类的最后一个实例中获取数据【英文标题】:TryingtouseXMLinGoogleSheetstogetdatafromlastinstanceofaclass【发布时间】:2022-01-2004:39:31【问题描述】:如果格式不正确,我们深表歉意;我以前从来没有在这里问... 查看详情

如何从类中获取“ReadOnly”或“WriteOnly”属性?

】如何从类中获取“ReadOnly”或“WriteOnly”属性?【英文标题】:Howtoget\'ReadOnly\'or\'WriteOnly\'propertiesfromaclass?【发布时间】:2013-03-0413:52:39【问题描述】:我需要从MyClass中获取属性列表,不包括“只读”属性,我可以获取它们吗... 查看详情

java示例代码_从类级注释冲突中获取属性路径

java示例代码_从类级注释冲突中获取属性路径 查看详情

抽象类和接口

接口是一种特殊的抽象类接口和抽象类的不同点:  1.抽象类中可以有实例属性;而接口中没有实例属性,Java虚拟机会自动给接口的加上publicstaticfianl修饰符,都是公开的静态常量  2.抽象类中可以有实例方法;而接口中没... 查看详情

类和实例(代码片段)

1.类属性a.由于python是动态语言,根据类创建的实例可以任意绑定属性。给实例绑定属性的方法是通过实例变量或者通过self变量classStudent(object):def__init__(self,name):self.name=namestd=Student(‘Tom‘)std.score=95 b.如果Student类本身需要绑定... 查看详情

如何从类属性(特别是 UIButton)访问父类实例?

】如何从类属性(特别是UIButton)访问父类实例?【英文标题】:HowcanIaccesstheparentclassinstancefromaclassattribute,specificallyaUIButton?【发布时间】:2016-09-0220:19:14【问题描述】:我有一个聊天气泡按钮,它调用一个菜单来将文本或图像... 查看详情