我有一个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
没有变量来保存它。