我尝试在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)
答案 0 :(得分:3)
这里有几个问题,但首先是:
__init__
,但既不接受 - 它们需要在签名中,而不仅仅是调用。在这种情况下,你无论如何都不需要它们;和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
不会覆盖它继承的任何方法。