python超级调用子方法 [英] python super calling child methods

查看:118
本文介绍了python超级调用子方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于super()的用法有很多问题,但是似乎没有一个问题可以回答我的问题.

There are numerous questions on the usage of super() but none of them appears to answer my question.

从子类中调用super().__init__()时,超级构造函数中的所有方法调用实际上都是从子类中进行的.考虑以下类结构:

When calling super().__init__() from a subclass, all method calls in the super-constructor are actually taken from the subclass. Consider the following class structure:

class A(object):
    def __init__(self):
        print("initializing A")
        self.a()
    def a(self):
        print("A.a()")

class B(A):
    def __init__(self):
        super().__init__()
        # add stuff for B
        self.bnum=3 # required by B.a()        
    def a(self):
        print("B.a(), bnum=%i"%self.bnum)

b=B()

失败

initializing A
Traceback (most recent call last):
  File "classmagic.py", line 17, in 
    b=B()
  File "classmagic.py", line 11, in __init__
    super().__init__()
  File "classmagic.py", line 5, in __init__
    self.a()
  File "classmagic.py", line 15, in a
    print("B.a(), bnum=%i"%self.bnum)
AttributeError: 'B' object has no attribute 'bnum'

在这里,我在B()中调用超级构造函数来初始化一些基本结构(其中一些作为自己的函数a()执行).但是,如果我也重写了a()函数,则在调用A的构造函数时会使用此实现,该构造函数会失败,因为AB一无所知,并且可能使用不同的内部变量.

Here I call the super constructor in B() to initialize some basic structure (some of which is executed as an own function a()). However, if I override the a() function as well, this implementation is used when calling A's constructor which fails because A knows nothing about B and may use different internal variables.

这可能是直观的,也可能不是直观的,但是当我希望A中的所有方法只能访问在那里实现的功能时该怎么办?

This may or may not be intuitive, but what do I have to do when I want all methods in A only to have access to the functions implemented there?

推荐答案

如果您的代码具有来调用无法覆盖的特定私有方法,请使用以两个下划线开头的名称:

If your code has to call specific private methods that cannot be overridden, use a name that starts with two underscores:

class A(object):
    def __init__(self):
        print("initializing A")
        self.__a()
    def __a(self):
        print("A.a()")

class B(A):
    def __init__(self):
        super().__init__()
        # add stuff for B
        self.bnum=3 # required by B.a()        
    def __a(self):
        print("B.__a(), bnum=%i"%self.bnum)

通过在类中添加

Python 缠结" 这样的方法名称名称(加上下划线),以最大程度地降低子类用其自己的版本覆盖它们的机会.

Python "mangles" such method names by adding in the class name (plus an underscore) to minimize the chances subclasses overwrite them with their own versions.

《 PEP 8 Python样式指南》 可以这样说:乱码:

如果打算将您的类设为子类,并且您具有属性 不想使用子类的对象,请考虑将其命名为 双前导下划线,无尾随下划线.这调用 Python的名称处理算法,其中类的名称为 改成属性名称.这有助于避免属性名称 碰撞子类应无意中包含带有 相同的名字.

If your class is intended to be subclassed, and you have attributes that you do not want subclasses to use, consider naming them with double leading underscores and no trailing underscores. This invokes Python's name mangling algorithm, where the name of the class is mangled into the attribute name. This helps avoid attribute name collisions should subclasses inadvertently contain attributes with the same name.

注1:请注意,整改后仅使用了简单的类名 名称,因此如果子类选择相同的类名和属性 名称,您仍然会遇到名称冲突.

Note 1: Note that only the simple class name is used in the mangled name, so if a subclass chooses both the same class name and attribute name, you can still get name collisions.

注2:名称修饰可以有某些用途,例如调试和 __getattr__(),不太方便.但是名称修改算法 有据可查且易于手动执行.

Note 2: Name mangling can make certain uses, such as debugging and __getattr__(), less convenient. However the name mangling algorithm is well documented and easy to perform manually.

注3:并非每个人都喜欢名字修饰.尝试平衡需要 避免高级呼叫者可能会意外使用名称冲突.

Note 3: Not everyone likes name mangling. Try to balance the need to avoid accidental name clashes with potential use by advanced callers.

这篇关于python超级调用子方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆