Python 2.7继承super()方法调用

时间:2016-03-12 08:15:26

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

我尝试在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)

1 个答案:

答案 0 :(得分:3)

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

  1. 您使用任意位置和关键字参数调用__init__,但既不接受 - 它们需要在签名中,而不仅仅是调用。在这种情况下,你无论如何都不需要它们;和
  2. 您的子类已经破坏了类的签名 - WebServer采用与Server不同的初始化参数,因此您不能使用另一个预期的对象。与Server中一样,您应该使用@classmethod作为替代初始化选项。
  3. 这是一个有效的实施方案:

    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不会覆盖它继承的任何方法。