加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 方法解析和调用如何在Python内部工作?

发布时间:2020-12-14 16:36:25 所属栏目:Java 来源:网络整理
导读:方法调用如何在 Python中工作? 我的意思是,python虚拟机如何解释它. 确实,Python中的python方法解析速度可能比Java慢. 什么是后期绑定? 这两种语言的反思机制有何不同? 哪里可以找到解释这些方面的好资源? 解决方法 Python中的方法调用包含两个不同的可
方法调用如何在 Python中工作?
我的意思是,python虚拟机如何解释它.

确实,Python中的python方法解析速度可能比Java慢.
什么是后期绑定?

这两种语言的反思机制有何不同?
哪里可以找到解释这些方面的好资源?

解决方法

Python中的方法调用包含两个不同的可分离步骤.首先进行属性查找,然后调用该查找的结果.这意味着以下两个片段具有相同的语义:
foo.bar()

method = foo.bar
method()

Python中的属性查找是一个相当复杂的过程.假设我们在对象obj上查找名为attr的属性,这意味着Python代码中的以下表达式:obj.attr

在第一个obj的实例字典中搜索“attr”,然后以“attr”的方法解析顺序搜索obj类的实例字典及其父类的字典.

通常,如果在实例上找到值,则返回该值.但是如果对类的查找导致一个具有__get__和__set__方法的值(确切地说,如果值类和父类的字典查找具有这两个键的值)那么类属性被视为某些东西称为“数据描述符”.这意味着调用该值的__get__方法,传入发生查找的对象并返回该值的结果.如果未找到class属性或不是数据描述符,则返回实例字典中的值.

如果实例字典中没有值,则返回类查找中的值.除非它碰巧是“非数据描述符”,即它具有__get__方法.然后调用__get__方法并返回结果值.

还有一个特殊情况,如果obj恰好是一个类(类型类型的实例),那么如果它是描述符并且相应地调用它,则还检查实例值.

如果在实例及其类层次结构中找不到值,并且obj的类具有__getattr__方法,则调用该方法.

下面显示了用Python编码的算法,有效地执行了getattr()函数的功能. (不包括任何漏掉的错误)

NotFound = object() # A singleton to signify not found values

def lookup_attribute(obj,attr):
    class_attr_value = lookup_attr_on_class(obj,attr)

    if is_data_descriptor(class_attr_value):
        return invoke_descriptor(class_attr_value,obj,obj.__class__)

    if attr in obj.__dict__:
        instance_attr_value = obj.__dict__[attr]
        if isinstance(obj,type) and is_descriptor(instance_attr_value):
            return invoke_descriptor(instance_attr_value,None,obj)
        return instance_attr_value

    if class_attr_value is NotFound:
        getattr_method = lookup_attr_on_class(obj,'__getattr__')
        if getattr_method is NotFound:
            raise AttributeError()
        return getattr_method(obj,attr)

    if is_descriptor(class_attr_value):
        return invoke_descriptor(class_attr_value,obj.__class__)

    return class_attr_value

def lookup_attr_on_class(obj,attr):
    for parent_class in obj.__class__.__mro__:
        if attr in parent_class.__dict__:
            return parent_class.__dict__[attr]
    return NotFound

def is_descriptor(obj):
    if lookup_attr_on_class(obj,'__get__') is NotFound:
        return False
    return True

def is_data_descriptor(obj):
    if not is_descriptor(obj) or lookup_attr_on_class(obj,'__set__') is NotFound :
        return False
    return True

def invoke_descriptor(descriptor,cls):
    descriptormethod = lookup_attr_on_class(descriptor,'__get__')
    return descriptormethod(descriptor,cls)

你问的方法调用所有这些描述符废话有什么用?嗯,问题是,这些函数也是对象,它们碰巧实现了描述符协议.如果属性查找在类上找到一个函数对象,则调用它的__get__方法并返回一个“绑定方法”对象.绑定方法只是函数对象周围的一个小包装器,它存储查找函数的对象,并且在调用时,将该对象预先添加到参数列表中(通常用于表示self参数的方法的函数) .

这是一些说明性的代码:

class Function(object):
    def __get__(self,cls):
        return BoundMethod(obj,cls,self.func)
    # Init and call added so that it would work as a function
    # decorator if you'd like to experiment with it yourself
    def __init__(self,the_actual_implementation):
        self.func = the_actual_implementation
    def __call__(self,*args,**kwargs):
        return self.func(*args,**kwargs)

class BoundMethod(object):
    def __init__(self,func):
        self.obj,self.cls,self.func = obj,func
    def __call__(self,**kwargs):
        if self.obj is not None:
             return self.func(self.obj,**kwargs)
        elif isinstance(args[0],self.cls):
             return self.func(*args,**kwargs)
        raise TypeError("Unbound method expects an instance of %s as first arg" % self.cls)

对于方法解析顺序(在Python的情况下实际上意味着属性解析顺序),Python使用来自Dylan的C3算法.这里解释起来太复杂了,所以如果你感兴趣的话请看this article.除非你正在做一些非常时髦的继承层次结构(你不应该这样做),否则就足以知道查找顺序是从左到右,深度优先,在搜索该类之前搜索类的所有子类.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读