GVKun编程网logo

Python超级方法和调用替代方法(python超级方法和调用替代方法的区别)

13

对于Python超级方法和调用替代方法感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解python超级方法和调用替代方法的区别,并且为您提供关于java–方法解析和调用如何在Python内部

对于Python超级方法和调用替代方法感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解python超级方法和调用替代方法的区别,并且为您提供关于java – 方法解析和调用如何在Python内部工作?、mac下python2.x和python3.x的安装方法和升级方法/卸载、NodeJS分叉的Python进程 – Python的process.send()的替代方案?、Python 2.7之前的dict理解的替代方法的宝贵知识。

本文目录一览:

Python超级方法和调用替代方法(python超级方法和调用替代方法的区别)

Python超级方法和调用替代方法(python超级方法和调用替代方法的区别)

我到处都看到应通过以下方式调用超类方法的示例:

super(SuperClass, instance).method(args)

这样做有什么不利之处吗?

SuperClass.method(instance, args)

答案1

小编典典

请考虑以下情况:

class A(object):    def __init__(self):        print(''Running A.__init__'')        super(A,self).__init__()class B(A):    def __init__(self):        print(''Running B.__init__'')                # super(B,self).__init__()        A.__init__(self)class C(A):    def __init__(self):        print(''Running C.__init__'')        super(C,self).__init__()class D(B,C):    def __init__(self):        print(''Running D.__init__'')        super(D,self).__init__()foo=D()

因此,这些类形成了一个所谓的继承钻石:

    A   / \  B   C   \ /    D

运行代码会产生

Running D.__init__Running B.__init__Running A.__init__

不好,因为跳过了Cs __init__。其原因是因为B__init__调用A__init__直接。

的目的super是解决继承钻石。如果您取消评论

# super(B,self).__init__()

和注释掉

A.__init__(self)

该代码产生了更令人满意的结果:

Running D.__init__Running B.__init__Running C.__init__Running A.__init__

现在,所有__init__方法都被调用。请注意,在当时你定义B.__init__你可能会 认为
super(B,self).__init__()是与调用A.__init__(self),但是你错了。在上述情况下,super(B,self).__init__()实际上调用C.__init__(self)

圣烟,
B一无所知C,却super(B,self)知道调用C__init__?原因是因为self.__class__.mro()包含C。换句话说,self(或以上所述foo)了解C

所以要小心-两者不可互换。它们可以产生截然不同的结果。

使用super 有陷阱。继承图中的所有类之间需要相当大的协调。(例如,它们必须具有相同的呼叫签名__init__,因为任何特定的__init__人都不知道__init__
super接下来会呼叫另一个,或者使用**kwargs。)此外,您必须在super任何地方都保持一致。跳过一次(如上例所示),您将失去的全部目的super。请参阅链接以了解更多陷阱。

如果您完全控制类的层次结构,或者避免使用继承菱形,则不需要super

java – 方法解析和调用如何在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.除非你正在做一些非常时髦的继承层次结构(你不应该这样做),否则就足以知道查找顺序是从左到右,深度优先,在搜索该类之前搜索类的所有子类.

mac下python2.x和python3.x的安装方法和升级方法/卸载

mac下python2.x和python3.x的安装方法和升级方法/卸载

一、首先问个问题,我们为什么要升级python2.x或者python3.x的版本?

一个是低版本会有些bug:或者功能问题,或者安全问题等,另外高版本会引进一些新的功能,也会废弃一些老的功能。

可以通过版本发布说明,了解这个版本的变化内容

二、那么我们为什么使用python3.x呢?

因为python3.x相比python2.x做了一些改动,引入了一些新的功能

目前来看两个版本还会并行存在一段时间,3.x会不会将来取代2.x,或者再出来一个4.x的版本。大家直接升级到4.x也说不准。

三、安装方法:

从官网:https://www.python.org/downloads/ 下载pkg的安装包,直接安装相应的版本,然后使用命令python2.x/pyhton3.x -m site查看安装包的路径。

四、升级方法:

同上,下载最新版本的pkg,直接安装,会覆盖低的版本。3.x的高版本覆盖3.x的低版本,当然不会覆盖2.x的版本。2.x升级也是一个道理

五、卸载:由于安装 Python 时,其自动生成:Python framework,即 Python 框架;Python 应用目录;指向 Python 的连接。所以卸载时,需要删除这些目录和连接。

  对于 Mac 自带的 Python,其框架目录为:/System/Library/Frameworks/Python.framework/,而我们安装的 Python,其(默认)框架目录为:/Library/Frameworks/Python.framework

  接下来,我们就分别(在 Mac 终端进行)删除上面所提到的三部分。

  第 1 步,删除框架:sudo rm -rf /Library/Frameworks/Python.framework/Versions/x.x
  第 2步,删除应用目录:sudo rm -rf "/Applications/Python x.x"
  第 3 步,删除指向 Python 的连接:cd /usr/local/bin/; ls -l /usr/local/bin | grep ''../Library/Frameworks/Python.framework/Versions/x.x'' | awk ''{print $9}'' | tr -d @ | xargs rm

其他操作系统linux、window的安装方法,基本差不多

NodeJS分叉的Python进程 – Python的process.send()的替代方案?

NodeJS分叉的Python进程 – Python的process.send()的替代方案?

我正在使用NodeJS分配Python脚本,并且在分叉时,默认情况下,NodeJS在此新进程和父进程之间创建一个IPC.

使用NodeJS,将消息从子节点发送到父节点,我执行process.send({msg:’toto’})

我怎么能用Python做到这一点?

http://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options

最佳答案
好的,我发现它,终于很容易了.它只是写在正确的文件描述符上.

在NodeJS端参数上,像这样生成你的脚本:

var child = child_process.spawn('python',['hello.py'],{
  stdio:[null,null,'ipc']
});

child.on('message',function(message) {
  console.log('Received message...');
  console.log(message);
});

由于’ipc’通道是第4个参数,您必须在filedescriptor 3上写入.
在Python方面:

import os

os.write(3,'{"dt" : "This is a test"}\n',"utf8")

完成.您将在child.on上收到消息(‘message’回调.

干杯!

Python 2.7之前的dict理解的替代方法

Python 2.7之前的dict理解的替代方法

如何使以下功能与Python 2.7之前的Python版本兼容?

gwfuncs = [reboot,flush_macs,flush_cache,new_gw,revert_gw,send_log]      
gw_func_dict = {chr(2**i): func for i,func in enumerate(gwfuncs[:8])}

今天关于Python超级方法和调用替代方法python超级方法和调用替代方法的区别的讲解已经结束,谢谢您的阅读,如果想了解更多关于java – 方法解析和调用如何在Python内部工作?、mac下python2.x和python3.x的安装方法和升级方法/卸载、NodeJS分叉的Python进程 – Python的process.send()的替代方案?、Python 2.7之前的dict理解的替代方法的相关知识,请在本站搜索。

本文标签: