Python 有没有办法从类中的方法生成函数

Python 有没有办法从类中的方法生成函数,python,function,class,oop,Python,Function,Class,Oop,我有一个数字类,其中有两个方法: def digit_sum(self): """Returns the sum of all the digits""" str_num = str(self.num) ans = Number(0) for item in str_num: ans += Number(item) retur

我有一个数字类,其中有两个方法:

    def digit_sum(self):
        """Returns the sum of all the digits"""
        str_num = str(self.num)
        ans = Number(0)
        for item in str_num:
            ans += Number(item)
        return ans

    def digit_product(self):
        """Returns the sum of all the digits"""
        str_num = str(self.num)
        ans = Number(1)
        for item in str_num:
            ans *= Number(item)
        return ans
我希望这些方法可以像函数一样访问,例如,我会键入
x=digit\u product(Number(54))

在python中有这样做的方法吗?

您已经可以将函数作为类的属性进行访问,如下所示:

Number.digit_product(Number(54))
如果您希望能够以名称
digit\u product
访问它,您只需执行以下操作:

digit_product = Number.digit_product

您已经可以作为类的属性访问该函数,如下所示:

Number.digit_product(Number(54))
如果您希望能够以名称
digit\u product
访问它,您只需执行以下操作:

digit_product = Number.digit_product

假设这些方法是在
Number
上定义的,它们已经是函数了;您可以通过执行以下操作来完成此操作:

x = Number.digit_product(Number(54))
如果您有一些场景,其中多个类可能提供相同名称的方法,但您只想调用与该类关联的方法,那么您可以编写一个简单的包装器:

def digit_product(x):
    return x.digit_product()
它将分派到适当的方法,同时仍然允许您以顶级函数语法调用它。如果变得更复杂(并非所有类型都有相同的方法,但您希望它适用于所有类型),则允许您专门化与特定类型相关的调用,而所有非专门化调用都尝试默认代码路径,例如:

from functools import singledispatch

@singledispatch
def digit_product(x):
    return x.digit_product()

@digit_product.register
def _(x: MyWeirdNumber):
    return x.my_weird_digit_product()

假设这些方法是在
Number
上定义的,它们已经是函数了;您可以通过执行以下操作来完成此操作:

x = Number.digit_product(Number(54))
如果您有一些场景,其中多个类可能提供相同名称的方法,但您只想调用与该类关联的方法,那么您可以编写一个简单的包装器:

def digit_product(x):
    return x.digit_product()
它将分派到适当的方法,同时仍然允许您以顶级函数语法调用它。如果变得更复杂(并非所有类型都有相同的方法,但您希望它适用于所有类型),则允许您专门化与特定类型相关的调用,而所有非专门化调用都尝试默认代码路径,例如:

from functools import singledispatch

@singledispatch
def digit_product(x):
    return x.digit_product()

@digit_product.register
def _(x: MyWeirdNumber):
    return x.my_weird_digit_product()

你能解释一下为什么这是可取的吗?这些函数/方法显然对非Numbers没有任何意义,那么为什么不直接使用Number(54).digit_product()?这有点奇怪。你能不能把
数字
类定义的其余部分,即
\uuuu init\uuuuu
和相关属性包括进来?我可以想象,你可能想这样做的一个原因是作为参数传递给
映射
排序
,或者类似的东西。例如,
numbers.sort(key=Number.digital\u product)
根据数字乘积对数字列表进行排序。实际上,参数不需要是
数字
;在这一点上,我们基本上是在讨论一个替代的构造函数,访问方式类似于
x=Number.digit\u product(54)
,你能解释一下为什么这是可取的吗?这些函数/方法显然对非Numbers没有任何意义,那么为什么不直接使用Number(54).digit_product()?这有点奇怪。你能不能把
数字
类定义的其余部分,即
\uuuu init\uuuuu
和相关属性包括进来?我可以想象,你可能想这样做的一个原因是作为参数传递给
映射
排序
,或者类似的东西。例如,
numbers.sort(key=Number.digital\u product)
根据数字乘积对数字列表进行排序。实际上,参数不需要是
数字
;在这一点上,我们基本上是在讨论另一个构造函数,访问方式类似于
x=Number.digit\u product(54)
如果要将其作为类的属性进行访问,则应该对其进行修饰
@classmethod
@staticmethod
,如果这样做,您将无法将其作为实例方法调用为
instance.method()
。不必将其设置为静态或类方法,也可以将其作为类的属性使用。@sabik:事实上,在这种特定情况下,使用
staticmethod
classmethod
是错误的;
self
参数是显式传递的,而不是像方法调用语法中那样隐式传递的,如果接收不到它(或尝试传递类,然后将实例作为参数传递),则会中断。如果传递的不是
self
,是不是…@sabik它是绑定到
self
的值。对于实例方法
bar
foo.bar()
type(foo).bar(foo)
是等效的(忽略继承)。对于类方法
bar
foo.bar()
type(foo).bar(type(foo))
是等效的。对于静态方法
bar
foo.bar()
type(foo).bar()
是等效的。如果要将其作为类的属性进行访问,则应将其修饰为
@classmethod
@staticmethod
,如果这样做,则可以将其作为实例方法调用为
实例方法()
。不必将其设置为静态或类方法,也可以将其作为类的属性使用。@sabik:事实上,在这种特定情况下,使用
staticmethod
classmethod
是错误的;
self
参数是显式传递的,而不是像方法调用语法中那样隐式传递的,如果接收不到它(或尝试传递类,然后将实例作为参数传递),则会中断。如果传递的不是
self
,是不是…@sabik它是绑定到
self
的值。对于实例方法
bar
foo.bar()
type(foo).bar(foo)
是等效的(忽略继承)。对于类方法
bar
foo.bar()
type(foo).bar(type(foo))
是等效的。对于静态方法
bar
foo.bar()
type(foo.bar()
是等效的。