精华内容
下载资源
问答
  • So if I have a class: class Person(object): '''A class with several methods that revolve around a person's... Python 2: super(Instructor, self).__init__(name, year) Python 3: super().__init__(name, year)

    So if I have a class:

    class Person(object):

    '''A class with several methods that revolve around a person's Name and Age.'''

    def __init__(self, name = 'Jane Doe', year = 2012):

    '''The default constructor for the Person class.'''

    self.n = name

    self.y = year

    And then this subclass:

    class Instructor(Person):

    '''A subclass of the Person class, overloads the constructor with a new parameter.'''

    def __init__(self, name, year, degree):

    Person.__init__(self, name, year)

    I'm a bit lost on how to get the subclass to call and use the parent class constructor for name and year, while adding the new parameter degree in the subclass.

    解决方案

    Python recommends using super().

    Python 2:

    super(Instructor, self).__init__(name, year)

    Python 3:

    super().__init__(name, year)

    展开全文
  • python 调用 父类构造方法, 以及调用普通方法的思考 文章目录一段代码引发的思考super 关键字super 两种写法的区别是什么?回到最初的问题参考文档 最近看一些 代码,产生 一些困惑 , 关于python中的调用父类的方法...

    python 调用 父类构造方法, 以及调用普通方法的思考


    最近看一些 代码,产生 一些困惑 , 关于python中的调用父类的方法以及 构造方法,有的方法 直接用类去调用.

    我不是很理解 这种写法,

    一段代码引发的思考

    下面是我看 WSGIServer 代码的时候,有一点疑惑 .

    server_bind() 这个实例方法 的调用 . 为啥要 用类名去调用一个 实例方法呢 ?

    class TCPServer:
        def server_bind(self):
            print("TCPServer server_bind() is  calling.")
            pass
    
    
    class HTTPServer(TCPServer):
        allow_reuse_address = 1  # Seems to make sense in testing environment
    
        def server_bind(self):
            """Override server_bind to store the server name."""
            TCPServer.server_bind(self)
    
    
    class WSGIServer(HTTPServer):
        """BaseHTTPServer that implements the Python WSGI protocol"""
    
        application = None
    
        def server_bind(self):
            """Override server_bind to store the server name."""
            HTTPServer.server_bind(self)
            self.setup_environ()
    
        def setup_environ(self):
            # Set up base environment
            env = self.base_environ = {}
            # env['SERVER_NAME'] = self.server_name
            env['GATEWAY_INTERFACE'] = 'CGI/1.1'
            # env['SERVER_PORT'] = str(self.server_port)
            env['REMOTE_HOST'] = ''
            env['CONTENT_LENGTH'] = ''
            env['SCRIPT_NAME'] = ''
    
        def get_app(self):
            return self.application
    
        def set_app(self, application):
            self.application = application
    
    

    这个继承关系 : WSGIServer --> HTTPServer --> TCPServer

    在 WSGIServer 里面 , server_bind 这个方法里面, HTTPServer.server_bind(self) 为啥要这样调用 server_bind 呢? 为啥不使用super 关键字去调用呢?

    为啥要使用 类名去调用一个 实例方法呢? 我陷入 了沉思 . 实例方法 不是要给实例对象来调用的吗, 不明白前辈们 当时写代码的想法. 带着好奇 我查了 一下资料 .

    super 关键字

    看着一段简单的代码 :

    class Person:
    
        def __init__(self):
            print('Person  __init__() is calling')
            self.name = 'person'
            pass
    
        def get_name(self):
            print(f"name:{self.name!r}")
    
    class Frank(Person):
    
        def __init__(self):
            print('Frank  __init__() is calling')
    
            self.myname = 'frank'
            pass
    
        def get_myname(self):
            print(f"myname:{self.myname!r}")
    
    
    if __name__ == '__main__':
        frank = Frank()
        frank.get_name()
        frank.get_myname()
    
        pass
    
    

    继承关系 中,如果一个方法在子类的实例中被调用,或者一个属性在子类的实例中被访问,但是该方法或属性在子类中并不存在,那么就会自动的去其父类中进行查找

    这里 就会报错

    AttributeError: ‘Frank’ object has no attribute ‘name’
    Frank init() is calling

    这里在调用 的时候 get_name 调用父类的方法 , 但是父类 self.name 并没有在子类进行初始化, 所有 就报错了 , 解决这个问题, 只要在初始化的时候, 加上父类的初始化

    class Frank(Person):
    
        def __init__(self):
            print('Frank  __init__() is calling')
            # 父类初始化
            Person.__init__(self)
            self.myname = 'frank'
            pass
        def get_myname(self):
            print(f"myname:{self.myname!r}")
    

    这样 就可以正常 出结果:

    Frank init() is calling
    Person init() is calling
    name:‘person’
    myname:‘frank’

    还有一种写法 : 使用关键字 super

    class Frank(Person):
    
        def __init__(self):
            print('Frank  __init__() is calling')
            # super关键字
            super(Frank, self).__init__()
            self.myname = 'frank'
            pass
    
        def get_myname(self):
            print(f"myname:{self.myname!r}")
    

    也可以这样写 :

    class Frank(Person):
    
        def __init__(self):
            print('Frank  __init__() is calling')
            # super(Frank, self).__init__()
            super().__init__()
            self.myname = 'frank'
            pass
    
        def get_myname(self):
            print(f"myname:{self.myname!r}")
    
    
    if __name__ == '__main__':
        frank = Frank()
        frank.get_name()
        frank.get_myname()
    
    

    以上写法 都可以在子类初始化的时候, 父类也就 初始化了. 看起来 结果 都一样 .

    但是 super 和 直接用类 调用 init() 方法 到底有什么区别 呢 ?

    总结了一下 有三种写法 :

    class Frank(Person):
    
        def __init__(self):
            print('Frank  __init__() is calling')
            # Person.__init__(self)
            # super().__init__()
            # super(Frank, self).__init__()
            super().__init__()
            self.myname = 'frank'
    

    以上者三种写法

    Person.init(self) 调用未绑定的超类构造方法

    super.init() 这样调用

    从这里来看几乎看不到区别

    下面的一段代码来自 python cookbook

    调用父类方法 https://python3-cookbook.readthedocs.io/zh_CN/latest/c08/p07_calling_method_on_parent_class.html

    class Base:
        def __init__(self):
            print('Base.__init__')
    
    class A(Base):
        def __init__(self):
            Base.__init__(self)
            print('A.__init__')
    
    class B(Base):
        def __init__(self):
            Base.__init__(self)
            print('B.__init__')
    
    class C(A,B):
        def __init__(self):
            A.__init__(self)
            B.__init__(self)
            print('C.__init__')
    
    >>> c = C()
    Base.__init__
    A.__init__
    Base.__init__
    B.__init__
    C.__init__
    

    从这里看 Base init 执行 了两次.

    如果 这样写 , 用 super 关键字 ,这样只会执行一次.

    class Base:
        def __init__(self):
            print('Base.__init__')
    
    class A(Base):
        def __init__(self):
            super().__init__()
            print('A.__init__')
    
    class B(Base):
        def __init__(self):
            super().__init__()
            print('B.__init__')
    
    class C(A,B):
        def __init__(self):
            super().__init__()  # Only one call to super() here
            print('C.__init__')
    
    c  = C()
    Base.__init__
    B.__init__
    A.__init__
    C.__init__
    

    这就是区别.

    这就是 python 中的多重继承的问题

    Python会计算出一个所谓的方法解析顺序(MRO)列表 ,super() 已经帮助我们 处理了这个关系,就不会调用 两次__init__() 方法.

    如果是在单继承 就不会出现这个问题. 所以super 就是为了解决这个问题而生的. 所以 是没有问题. python cook book 作者也推荐 使用 super .

    super 两种写法的区别是什么?

    还有一个问题 : super 两种写法 到底有什么区别 ?

    super(Frank, self).init()

    super().init()

    其实 super 关键字 PEP 3135 – New Super New Super

    给出了 说明:

    image-20190901083516319

    ​ 这个是两种写法, 现在已经不需要在super() 里面传入任何关键字了. 直接使用第一种写法 就可以了. super().foo(1,2) 这个是比较新的写法 . 在supe() 里面传入类名,是旧的写法.

    回到最初的问题

    文章开头的疑问

    server_bind() 为啥 要用类名调用一个实例方法呢?

    image-20190901083826113

    image-20190901083854294

    作者这样 写法 首先不是错误, 因为 本身就是单继承,不会出现方法被调用多次的情况 . 所以应该没有什么问题 .

    但是作者为啥这样写, 本人猜测 这些代码是 很久以前写的,

    那个时候super 支持并不是特别好, 所以就使用了比较原始的写法 , 但是看到这样的代码,也不要感觉奇怪. 只是以后 我们在写法 的时候 , 要新的方式写就可以了 . 接受别以前的代码, 自己写代码用最新的方式就好了.

    class WSGIServer(HTTPServer):
        """BaseHTTPServer that implements the Python WSGI protocol"""
    
        application = None
    
        def server_bind(self):
            """Override server_bind to store the server name."""
            # HTTPServer.server_bind(self)
            # 这样写可以了. 
            super().server_bind()
            self.setup_environ()
    

    参考文档

    python子类调用父类的方法 http://www.crazyant.net/1303.html

    PEP 3135 – New Super https://www.python.org/dev/peps/pep-3135/

    8.7 调用父类方法 https://python3-cookbook.readthedocs.io/zh_CN/latest/c08/p07_calling_method_on_parent_class.html

    分享快乐,留住感动. '2019-09-03 19:33:38' --frank
    展开全文
  • 如果子类和父类都有构造函数,子类其实是重写了父类的构造函数,如果不显式调用父类构造函数,父类的构造函数就不会被执行,导致子类实例访问父类初始化方法中初始的变量就会出现问题。 参考 ...

     

    子类不显式调用父类的构造方法,而父类构造函数初始化了一些属性,就会出现问题

    如果子类和父类都有构造函数,子类其实是重写了父类的构造函数,如果不显式调用父类构造函数,父类的构造函数就不会被执行,导致子类实例访问父类初始化方法中初始的变量就会出现问题。

     

     

     

     

     

    参考 https://www.cnblogs.com/lindaxin/p/7986227.html

    转载于:https://www.cnblogs.com/baxianhua/p/10819926.html

    展开全文
  • from:http://www.crazyant.net/1303.htmlpython和其他面向对象语言类似,每个类可以拥有一个或者多个父类,它们从...继承父类后,就能调用父类方法和访问父类属性,而要完成整个集成过程,子类是需要调用的构造函...

    from:http://www.crazyant.net/1303.html

    python和其他面向对象语言类似,每个类可以拥有一个或者多个父类,它们从父类那里继承了属性和方法。如果一个方法在子类的实例中被调用,或者一个属性在子类的实例中被访问,但是该方法或属性在子类中并不存在,那么就会自动的去其父类中进行查找。

    继承父类后,就能调用父类方法和访问父类属性,而要完成整个集成过程,子类是需要调用的构造函数的。

    子类不显式调用父类的构造方法,而父类构造函数初始化了一些属性,就会出现问题

    如果子类和父类都有构造函数,子类其实是重写了父类的构造函数,如果不显式调用父类构造函数,父类的构造函数就不会被执行,导致子类实例访问父类初始化方法中初始的变量就会出现问题。

    class A:

    def __init__(self):

    self.namea="aaa"

    def funca(self):

    print("function a : %s"%self.namea)

    class B(A):

    def __init__(self):

    self.nameb="bbb"

    def funcb(self):

    print("function b : %s"%self.nameb)

    b=B()

    print(b.nameb)

    b.funcb()

    b.funca()

    结果:

    bbb

    function b : bbb

    Traceback (most recent call last):

    File "/home/lai/workspace/sru/2.py", line 24, in

    b.funca()

    File "/home/lai/workspace/sru/2.py", line 11, in funca

    print("function a : %s"%self.namea)

    AttributeError: 'B' object has no attribute 'namea'

    在子类中,构造函数被重写,但新的构造方法没有任何关于初始化父类的namea属性的代码,为了达到预期的效果,子类的构造方法必须调用其父类的构造方法来进行基本的初始化。有两种方法能达到这个目的:调用超类构造方法的未绑定版本,或者使用super函数。

    方法一:调用未绑定的超类构造方法

    修改代码,多增一行:

    class A:

    def __init__(self):

    self.namea="aaa"

    def funca(self):

    print("function a : %s"%self.namea)

    class B(A):

    def __init__(self):

    self.nameb="bbb"

    #这一行解决了问题

    A.__init__(self)

    def funcb(self):

    print("function b : %s"%self.nameb)

    b=B()

    print(b.nameb)

    b.funcb()

    b.funca()

    结果

    bbb

    function b : bbb

    function a : aaa

    如上有注释的一行解决了该问题,直接使用父类名称调用其构造函数即可。

    这种方法叫做调用父类的未绑定的构造方法。在调用一个实例的方法时,该方法的self参数会被自动绑定到实例上(称为绑定方法)。但如果直接调用类的方法(比如A.__init),那么就没有实例会被绑定。这样就可以自由的提供需要的self参数,这种方法称为未绑定unbound方法。

    通过将当前的实例作为self参数提供给未绑定方法,B类就能使用其父类构造方法的所有实现,从而namea变量被设置。

    方法二:使用super函数

    修改代码,这次需要增加在原来代码上增加2行:

    #父类需要继承object对象

    class A(object):

    def __init__(self):

    self.namea="aaa"

    def funca(self):

    print("function a : %s"%self.namea)

    class B(A):

    def __init__(self):

    #这一行解决问题

    super(B,self).__init__()

    self.nameb="bbb"

    def funcb(self):

    print("function b : %s"%self.nameb)

    b=B()

    print(b.nameb)

    b.funcb()

    b.funca()

    结果与方法一相同

    bbb

    function b : bbb

    function a : aaa

    如上有注释的为新增的代码,其中第一句让类A继承自object类,这样才能使用super函数,因为这是python的“新式类”支持的特性。当前的雷和对象可以作为super函数的参数使用,调用函数返回的对象的任何方法都是调用超类的方法,而不是当前类的方法。

    super函数会返回一个super对象,这个对象负责进行方法解析,解析过程其会自动查找所有的父类以及父类的父类。

    方法一更直观,方法二可以一次初始化所有超类

    super函数比在超累中直接调用未绑定方法更直观,但是其最大的有点是如果子类继承了多个父类,它只需要使用一次super函数就可以。然而如果没有这个需求,直接使用A.__init__(self)更直观一些。

    展开全文
  • 本文实例讲述了Python实现子类调用父类方法。分享给大家供大家参考。具体实现方法如下:python和其他面向对象语言类似,每个类可以拥有一个或者多个父类,它们从父类那里继承了属性和方法。如果一个方法在子类的...
  • 1. python3 和python2 调用父类构造方法写法区别前一段时间,把之前的一个项目迁移到python3发现了很多不同的地方.我这里简单说明了,构造方法的不同 之后可能会继续更新不同. 主要针对项目迁移进行总结,反思. 这里就...
  • super().__init__(父类构造函数需要的参数,不包括self) class People: def __init__(self, name, age): self.name = name self.age = age class Student(People): def __init__(self, name,...
  • python中子类调用父类构造方法

    千次阅读 2014-06-02 02:03:27
    python和其他面向对象语言类似,每个类可以拥有一个或者多个父类,它们从父类那里继承了属性和方法。如果一个方法在子类的实例中被调用,或者一个属性在子类...子类不显式调用父类构造方法,而父类构造函数初始化了一
  • 2.使用未绑定方法调用父类构造方法 3.使用super()函数调用父类的构造方法 重点 ''' class FuleiFun: def __init__(self, num): self.num = num * 2 print('父类名称%s' % num) def toolsFun(self): print('父类
  • F:\python\python.exe F:/python程序/test.py Traceback (most recent call last): File "F:/python程序/test.py", line 17, in s=Student("janie","woman","student") File "F:/python程序/test.py", line 13...
  • python中通过super()调用父类构造方法

    千次阅读 2017-10-28 12:05:17
    可能是java写多了,当我准备通过super(self,xxx)这样调用父类构造方法时候,一直报错,上网查资料,发现python的super()的机制和java还是有很大区别的。 首先看一下super()函数的定义 super([type[,object-or-...
  • Python调用父类方法-super

    千次阅读 2019-01-01 14:51:23
    在子类中调用父类的某个已经被覆盖的方法,需要使用 super() 函数。 class Parent(object): def spam(self): print('Parent.spam') class Child(Parent): def spam(self): print('Child.spam') super().s....
  • Python 调用父类方法

    2018-11-09 18:11:00
    ____tz_zs未完 ...因为你可能会调用两次共享基类的构造函数。 class Human(object): def __init__(self, age): self.age = age print "Human age:%s:" % age class Student(...
  • class Car: def __init__(self,name): self.name = name print('父类构造方法调用。。。') class AutoCar(Car): def __init__(self,name,age): #Car.__init__(self,name) #方式...
  • 本文实例讲述了Python实现子类调用父类的方法。分享给大家供大家参考。具体实现方法如下: ...如果子类和父类都有构造函数,子类其实是重写了父类的构造函数,如果不显式调用父类构造函数,父类的构造
  • 当一个类被子类继承且子类重写了构造方法后,若子类还想使用父类的构造方法,如果直接通过创建的子类对象调用父类的方法会报错。解决办法有两个:一个是调用超类方法的未绑定版本,一个是使用super函数 见下面的例子...
  • 1、显示调用父类构造方法 2、不重写父类构造方法
  • Python 子类调用父类方法

    千次阅读 2016-09-07 15:03:24
    Python实现子类调用父类方法

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 29,822
精华内容 11,928
关键字:

python调用父类的构造方法

python 订阅