Python class 中的静态重载方法。缺少参数问题
Static overloaded method in Python class. Missing argument issue
我有一个 class db
定义如下:
class db:
def __init_(self, idx, host, port, db_name, user, password):
self.idx = idx
...
def Connect(self):
conn = db_engine.connect(host=self.host, ...)
@staticmethod
def Connect(idx):
if idx == 1:
d = db(1, "localhost", 80, ...)
conn = d.Connect()
return conn
因此,如您所见,我的 class 有两种方法。最重要的是它有一个静态方法Connect
,它在内部尝试调用一个非静态方法Connect
。但是,当我尝试使用我的程序时,我收到一条错误消息:
d.Connect()
TypeError: Connect() missing 1 required positional argument ...
静态方法似乎试图调用自身,但我想让它调用另一个非静态方法。那么,我做错了什么?
您重新定义了 Count
方法。 Python 不支持重载;您不能同时定义常规方法和静态方法。您 只有 有 staticmethod
版本,因为它是最后定义的,它完全取代了非静态版本。
如果您需要一种根据绑定与否改变其行为的方法(静态方法与常规方法),您有两种选择;测试 self
参数的类型(它将是整数或 db
class 的实例),或者您必须构建自定义 descriptor object这可以根据上下文改变您的方法的调用方式;在实例上或 class.
测试 self
的类型如下所示:
class db:
def __init_(self, idx, host, port, db_name, user, password):
self.idx = idx
# ...
def Connect(self_or_idx):
if isinstance(self_or_idx, db):
self = self_or_idx
conn = db_engine.connect(host=self.host, ...)
# ...
else:
idx = self_or_idx
if idx == 1:
d = db(1, "localhost", 80, ...)
conn = d.Connect()
return conn
如果使用自定义描述符,您可以构建一个支持两种不同功能的描述符like the property
object does:
class static_or_instance_method(object):
def __init__(self, instancemethod=None, staticmethod=None):
self.method = instancemethod
self.static = staticmethod
def staticmethod(self, staticmethod):
return type(self)(self.method, staticmethod)
def instancemethod(self, instancemethod):
return type(self)(instancemethod, self.static)
def __get__(self, instance, cls=None):
if instance is None:
return self.static
return self.method.__get__(instance, cls)
然后像这样使用它:
class db:
def __init_(self, idx, host, port, db_name, user, password):
self.idx = idx
# ...
@static_or_instance_method
def Connect(self):
conn = db_engine.connect(host=self.host, ...)
# ...
@Connect.staticmethod
def Connect(idx):
if idx == 1:
d = db(1, "localhost", 80, ...)
conn = d.Connect()
return conn
描述符的快速演示:
>>> class Foo:
... @static_or_instance_method
... def bar(self):
... return 'Bound method of {}'.format(self)
... @bar.staticmethod
... def bar(arg):
... return 'Static method, receiving argument {}'.format(arg)
...
>>> Foo().bar()
'Bound method of <__main__.Foo object at 0x10b6cf588>'
>>> Foo.bar('spam')
'Static method, receiving argument spam'
我有一个 class db
定义如下:
class db:
def __init_(self, idx, host, port, db_name, user, password):
self.idx = idx
...
def Connect(self):
conn = db_engine.connect(host=self.host, ...)
@staticmethod
def Connect(idx):
if idx == 1:
d = db(1, "localhost", 80, ...)
conn = d.Connect()
return conn
因此,如您所见,我的 class 有两种方法。最重要的是它有一个静态方法Connect
,它在内部尝试调用一个非静态方法Connect
。但是,当我尝试使用我的程序时,我收到一条错误消息:
d.Connect()
TypeError: Connect() missing 1 required positional argument ...
静态方法似乎试图调用自身,但我想让它调用另一个非静态方法。那么,我做错了什么?
您重新定义了 Count
方法。 Python 不支持重载;您不能同时定义常规方法和静态方法。您 只有 有 staticmethod
版本,因为它是最后定义的,它完全取代了非静态版本。
如果您需要一种根据绑定与否改变其行为的方法(静态方法与常规方法),您有两种选择;测试 self
参数的类型(它将是整数或 db
class 的实例),或者您必须构建自定义 descriptor object这可以根据上下文改变您的方法的调用方式;在实例上或 class.
测试 self
的类型如下所示:
class db:
def __init_(self, idx, host, port, db_name, user, password):
self.idx = idx
# ...
def Connect(self_or_idx):
if isinstance(self_or_idx, db):
self = self_or_idx
conn = db_engine.connect(host=self.host, ...)
# ...
else:
idx = self_or_idx
if idx == 1:
d = db(1, "localhost", 80, ...)
conn = d.Connect()
return conn
如果使用自定义描述符,您可以构建一个支持两种不同功能的描述符like the property
object does:
class static_or_instance_method(object):
def __init__(self, instancemethod=None, staticmethod=None):
self.method = instancemethod
self.static = staticmethod
def staticmethod(self, staticmethod):
return type(self)(self.method, staticmethod)
def instancemethod(self, instancemethod):
return type(self)(instancemethod, self.static)
def __get__(self, instance, cls=None):
if instance is None:
return self.static
return self.method.__get__(instance, cls)
然后像这样使用它:
class db:
def __init_(self, idx, host, port, db_name, user, password):
self.idx = idx
# ...
@static_or_instance_method
def Connect(self):
conn = db_engine.connect(host=self.host, ...)
# ...
@Connect.staticmethod
def Connect(idx):
if idx == 1:
d = db(1, "localhost", 80, ...)
conn = d.Connect()
return conn
描述符的快速演示:
>>> class Foo:
... @static_or_instance_method
... def bar(self):
... return 'Bound method of {}'.format(self)
... @bar.staticmethod
... def bar(arg):
... return 'Static method, receiving argument {}'.format(arg)
...
>>> Foo().bar()
'Bound method of <__main__.Foo object at 0x10b6cf588>'
>>> Foo.bar('spam')
'Static method, receiving argument spam'