Python:避免同时定义classmethod和instancemethod

Python:避免同时定义classmethod和instancemethod,python,Python,请注意以下问题。我认为“正确的”python习惯用法是a)创建模块函数,例如下面的foo_math,然后对类本身中的实例调用它们的特定操作。下面的代码反映了这种方法 我想定义一个classmethod,它接受两个参数并返回一个值。我希望能够在实例值pass作为参数之一的类实例上调用相同的方法。我可以在不定义两个不同方法的情况下完成这项工作吗 class Foo(object): __init__(x): self.x = x @classmethod

请注意以下问题。我认为“正确的”python习惯用法是a)创建模块函数,例如下面的
foo_math
,然后对
类本身中的实例调用它们的特定操作。下面的代码反映了这种方法


我想定义一个
classmethod
,它接受两个参数并返回一个值。我希望能够在实例值pass作为参数之一的
实例上调用相同的方法。我可以在不定义两个不同方法的情况下完成这项工作吗

class Foo(object):
    __init__(x):
        self.x = x

    @classmethod
    def foo_math(cls, x, y):
         return x + y

    def math(self, y):
        return Foo.foo_math(self.x, y)
我想要的是:

>>> Foo.math(3, 4)
7
>>> f = Foo()
>>> f.x = 3
>>> f.math(4)
7
除了子类型
int
,以下是我对这个问题的结论:

def foo_math(cls, x, y):
     return x + y

class Foo(object):
    __init__(x):
        self.x = x

    def foo_math(self, y):
        return foo_math(self, y)

我认为,如果不定义某个类的对象,就不能从该类调用方法(类方法不属于任何一个类的方法),因此像
Foo.math(3,4)
之类的东西将返回
NameError
,因为
Foo
尚未定义

考虑到这一点,您应该将代码修改为这样(即使问题解决后,代码仍存在一些问题):

然后你可以做:

>>> f = Foo(3)
>>> f.math(4)
7

我不建议您这样做,但如果您真的想这样做的话,可以这样做(感谢stackoverflow上的其他人在第一部分):

然后,做一些类似的事情

class F(object):
    @staticorinstancemethod
    def math(instOrNone, v1, v2=None):
        return instOrNone.x + v1 if instOrNone else v1 + v2

但是也许你只是想定义
\uuuu add\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
。。我的学习python待办事项列表中的另一项。既然我想符合“沉重的期望”,那么有没有一种常规的方法来处理命名非常相似的
classmethod
instancemethod
?为什么要这样做?看起来你试图解决的问题可能不是实际解决的最佳问题。@AdamCushner怎么会这样?我仍然在思考如何做这个
阶段,所以任何额外的反馈都是很好的。哦,我的意思是你能给出一个好的用例吗?看起来你要么想做一件,要么想做另一件。你能说明一下为什么你需要同时做这两件事吗?此外,您可能需要考虑运算符重载。好主意。我同意你的不推荐。但是谢谢你的体贴。
class staticorinstancemethod(object):
    def __init__(self, func):
        self.func = func

    def __get__(self, instance, owner):
        return functools.partial(self.func, instance)
class F(object):
    @staticorinstancemethod
    def math(instOrNone, v1, v2=None):
        return instOrNone.x + v1 if instOrNone else v1 + v2