提问人:Parikshit 提问时间:9/10/2023 最后编辑:Parikshit 更新时间:9/10/2023 访问量:50
我应该检查类属性的输入类型吗?
Should I check the type of input to my class properties?
问:
我是一个相当新的Python开发人员,并且已经习惯了“鸭子打字”的想法。
我在另一个模块中使用了一个类来对它执行特定操作,例如,访问它的名称和版本。这个模块显然不能处理任意值,需要名称是字符串,版本是整数。
目前,我正在使用 isinstance() 强制执行类属性的输入类型:
class ExampleObject(object):
def __init__(self):
self._name = None
self._version = None
@property
def name(self):
return self._name
@name.setter
def name(self, name):
if not isinstance(name, str) and name is not None:
raise ValueError("Expected string, got {0}".format(type(name)))
self._name = name
@property
def version(self):
return self._name
@version.setter
def version(self, version_number):
if not isinstance(version_number, int) and version_number is not None:
raise ValueError("Expected int, got {0}".format(type(version_number)))
self._version = version_number
如果我采用 Duck 类型的想法,我不应该对我的属性强制执行特定类型。如果我放弃了类型检查,而其他一些开发人员开始将这些属性用于其他数据类型,则可能导致我编写的模块中断。基本上,模块期望一个整数,它得到其他东西。正确的方法是什么?
我检查了几个与此相关的问题,但没有一个涉及如果我们跳过类型检查会发生什么,以及如何强制其他开发人员不会破坏某些东西,因为他们不知道另一个模块使用这些属性来执行特定于类型的事情。
答:
Python 的鸭子类型让你有责任强制执行它。如果参数将由用户传递,则最好执行强制转换和/或类型验证。例如,您可以尝试使用内置方法转换为 int。如果此操作失败(即。 cannot be converted to a string),该方法会为您引发一个 ValueError,您可以按如下方式检查:version_number
int()
version_number
int()
@version.setter
def version(self, version_number):
try:
version_number = int(version_number)
except ValueError: #when casting to int fails, Python raises a ValueError
# handle error here
#otherwise, version_number is now a valid int, so continue
如果你是唯一一个使用你的代码的人,你可以放弃此验证,风险由你自己承担。无论您选择哪种方式,使用类型提示也是一个好主意。类型提示在运行时不执行任何操作(因此它们不会为您执行任何强制转换/验证),但可以帮助 IDE 提醒您参数或返回值的预期类型。函数的类型提示可能如下所示:
@version.setter
def version(self, version_number: int) -> None:
该参数不需要任何类型提示,因为 IDE 可以看出 将是 .参数上的类型提示指示此参数应为 int。最后,返回类型提示 表示此函数不返回任何内容。self
self
ExampleObject
int
version_number
None
来源: https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html
评论