在python 2中,函数可以是静态的还是非静态的

在python 2中,函数可以是静态的还是非静态的,python,python-2.x,Python,Python 2.x,假设我有一门课: class Test(object): def __init__(self, a): self.a = a def test(self, b): if isinstance(self, Test): return self.a + b else: return self + b 在我的世界里,这样做最理想: >>> Test.test(1,2)

假设我有一门课:

class Test(object):
    def __init__(self, a):
        self.a = a

    def test(self, b):
        if isinstance(self, Test):
            return self.a + b
        else:
            return self + b
在我的世界里,这样做最理想:

>>> Test.test(1,2)
3
>>> Test(1).test(2)
3
现在,这不起作用,因为您遇到以下错误:

TypeError: unbound method test() must be called with Test instance as first argument (got int instance instead)
在python3中,这工作得很好,我暗自怀疑这在python2中的装饰器中是可能的,但我的python foo不够强大,无法让它工作


Plot Twist:当我需要在self上调用某个东西时,如果它不是静态调用的,会发生什么情况。

如果您希望某个东西在实例上调用时实际接收到
self
,但也可以在类上调用,那么最好编写自己的描述符类型:

import types

class ClassOrInstanceMethod(object):
    def __init__(self, wrapped):
        self.wrapped = wrapped
    def __get__(self, instance, owner):
        if instance is None:
            instance = owner
        return self.wrapped.__get__(instance, owner)

class demo(object):
    @ClassOrInstanceMethod
    def foo(self):
        # self will be the class if this is called on the class
        print(self)

对于问题的原始版本,您可以像编写任何其他静态方法一样,使用
@staticmethod
。在实例上调用静态方法的工作原理与在类上调用静态方法的工作原理相同:

class Test(object):
    @staticmethod
    def test(a, b):
        return a + b

如果您想要在实例上调用时实际接收到的
self
,但也可以在类上调用,那么最好编写自己的描述符类型:

import types

class ClassOrInstanceMethod(object):
    def __init__(self, wrapped):
        self.wrapped = wrapped
    def __get__(self, instance, owner):
        if instance is None:
            instance = owner
        return self.wrapped.__get__(instance, owner)

class demo(object):
    @ClassOrInstanceMethod
    def foo(self):
        # self will be the class if this is called on the class
        print(self)

对于问题的原始版本,您可以像编写任何其他静态方法一样,使用
@staticmethod
。在实例上调用静态方法的工作原理与在类上调用静态方法的工作原理相同:

class Test(object):
    @staticmethod
    def test(a, b):
        return a + b

哇哦,只是添加了
@staticmethod
装饰器就行了…哇哦,只是添加了
@staticmethod
装饰器就行了…但是考虑到可选的
self
参数:@albertjan:静态方法不会收到隐式的
self
,即使你在实例上调用它们也是如此。这正是我想要的,难道
MethodType
会成为一个新的“绑定”方法吗?@albertjan:是的。它还可以在Python2上创建未绑定的方法对象;
instance=owner
位避免了这种情况。(另外,我现在更改了代码以创建不同的方法对象,因为Python 3中
types.MethodType
的签名已更改。这种方式应与2和3兼容。)但考虑到可选的
self
参数:@albertjan:静态方法不会收到隐式的
self
,即使你在实例上调用它们也是如此。这正是我想要的,难道
MethodType
会成为一个新的“绑定”方法吗?@albertjan:是的。它还可以在Python2上创建未绑定的方法对象;
instance=owner
位避免了这种情况。(另外,我现在更改了代码以创建不同的方法对象,因为在Python 3中,
types.MethodType
的签名已更改。这种方式应该与2和3兼容。)