【问题标题】:Python 2.7 inheritance super() method invocationPython 2.7 继承 super() 方法调用
【发布时间】:2016-06-27 14:09:10
【问题描述】:

我确实尝试在 Python 2.7 中使用继承并创建第二个类,该类将使用 super 方法和 @classmethod 装饰器来初始化基类。但是,即使将*args**kwargs 参数添加到初始化基类的函数中,我仍然无法使其工作。

import socket


class Server(object):

    def __init__(self, ip_address, host):
        self.ip_address = ip_address
        self.host = host

    @classmethod
    def create_with_host(cls, host, *args, **kwargs):
        ip_address = socket.gethostbyname(host)
        return cls(ip_address, host, *args, **kwargs)


class WebServer(Server):

    def __init__(self, url):
        super(WebServer, self).create_with_host(url.split('/')[2])
        self.url = url


if __name__ == '__main__':
    s1 = Server.create_with_host('www.google.com')
    print(s1.host, s1.ip_address)
    w1 = WebServer('http://app.pluralsight.com')
    print(w1.host, w1.ip_address, w1.url)

错误是:

Traceback (most recent call last):
  File "/Users/poc.py", line 26, in <module>
    w1 = WebServer('http://app.pluralsight.com')
  File "/Users/poc.py", line 19, in __init__
    super(WebServer, self).create_with_host(url.split('/')[2])
  File "/Users/poc.py", line 13, in create_with_host
    return cls(ip_address, host, *args, **kwargs)
TypeError: __init__() takes exactly 2 arguments (3 given)

【问题讨论】:

    标签: python python-2.7 inheritance super python-decorators


    【解决方案1】:

    这里有几个问题,但首先是:

    1. 您正在使用任意位置和关键字参数调用__init__,但都不接受这些 - 它们需要在签名中,而不仅仅是在调用中。在这种情况下,您实际上并不需要它们。和
    2. 您的子类化破坏了类的签名 - WebServer 采用与 Server 不同的初始化参数,因此您不能在预期的地方使用一个。与Server 一样,您应该使用@classmethod 作为替代初始化选项。

    这是一个有效的实现:

    import socket
    
    
    class Server(object):
    
        def __init__(self, ip_address, host):
            self.ip_address = ip_address
            self.host = host
    
        @classmethod
        def create_with_host(cls, host):
            ip_address = socket.gethostbyname(host)
            return cls(ip_address, host)
    
    
    class WebServer(Server):
    
        @classmethod
        def create_with_url(cls, url):
            inst = cls.create_with_host(url.split('/')[2])
            inst.url = url
            return inst
    

    请注意,这里不需要super,因为WebServer 不会覆盖它继承的任何方法。

    【讨论】:

    • 谢谢...您的观察是有道理的,并且代码更具可读性。第二……是我第一次看到“inst”的用法。回到书本……
    • @CezarSpatariuNeagu inst 没有什么特别之处,你可以随便命名它——它只是类方法返回的新实例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-11
    • 1970-01-01
    • 2016-06-24
    • 2018-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多