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'