将模块函数作为静态方法导入到类中



我有一个python模块helpers.py


def str_to_num(s: str):
'''Converts to int if possible else converts to float if possible
Returns back the string if not possible to convert to a number.
'''
# NOTE: These are not really funcs, but classes.
funcs = [int, float]
for func in funcs:
try:
res = func(s)
break
except ValueError:
continue
else:
res = s
return(res)

我还有另一个模块string_number.py

from helpers import str_to_num
class StringNumber:
def __init__(self, s):
self.s = s
str_to_num = str_to_num
@property
def value(self):
return(self.str_to_num(self.s))
def __repr__(self):
return(f'{self.__class__.__name__}({repr(self.s)})')
>>> from string_number import StringNumber
>>> sn = StringNumber(1)
>>> sn.value 
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "string_number.py", line 19, in value
return(self.str_to_num(self.s))
TypeError: str_to_num() takes 1 positional argument but 2 were given

但是,当从类访问函数时,这有效:

>>> StringNumber.str_to_num(1)
1

Q.1:为什么从实例访问str_to_num属性时需要两个参数?自我被传递给它了吗?如果是这样,为什么?

现在,我知道我可以添加修改__init__方法以使其成为实例的属性

def __init__(self, s):
self.s = s
self.str_to_num = str_to_num

此外,我可以通过创建一个 Helper 函数类然后从中继承来解决此问题。

from helpers import str_to_num
class Helper:
@staticmethod
def str_to_num(s):
return(str_to_num(s))

class StringNumber(Helper):
def __init__(self, s):
self.s = s
@property
def value(self):
return(self.str_to_num(self.s))
def __repr__(self):
return(f'{self.__class__.__name__}({repr(self.s)})')

问:2有没有办法在不使用继承的情况下使模块函数,即类的静态方法?或者这是一个非常糟糕的做法?

问:3假设我有一个helpers.py模块,其中包含大量的模块功能。要将它们作为静态方法合并到我的类中,最好的方法是什么,而不创建一个单独的Helper类?

Q.1:为什么从实例访问 str_to_num 属性时需要两个参数?自我被传递给它了吗?如果是这样,为什么?

你写了"但是,从类访问函数时这有效:StringNumber.str_to_num(1)"。它之所以有效,是因为您已通过在类定义下定义方法将方法声明为静态方法。

与静态方法相反,实例方法在调用实例时确实将实例作为第一个参数传递。因此,当您调用instance.str_to_num(1)str_to_num(s: str)时 - 无论您的类型如何将其暗示为字符串 - 都将实例作为s参数接收并抱怨值1没有变量来保存它。

最新更新