如何解决如何注释功能参数的最大限制
例如
def function(param):
# do something
# return value
通过使用Type hints,我可以使用户了解参数param
的类型和返回值value
,如下所示:
def function(param : int)-> str:
# do something
# return value
是否可以让用户知道可以传递给函数function
的最大值?
解决方法
可以在设计时由编译器或预编译器检查(某种程度上)参数的类型。例如,如果您使用一些变量或表达式作为参数来调用函数,则编译器可以检查表达式是否应具有与参数期望的类型相同的类型。
但是,只能在运行时(即程序运行时)确定参数的 value 。因此,不,您无法获得以这种方式限制参数的类型提示。不过,您可以让一个文档字符串提供该信息,这样用户便可以查明是否进行了检查,但是编译器或IDE将无济于事。
还有另外两种解决方法:
- 定义一个新类型,该类型只能具有您愿意允许的值范围
- 让函数在传递错误值时引发一个异常(在运行时)
一种新类型:
class Int0To9(int):
def __init__(self,value):
assert value in range(10)
super().__init__()
def my_func(x: Int0To9):
print(x)
# this one will work,but shows a type hint in a good IDE
my_func(1)
# this one will also work,but shows a type hint in a good IDE - this may be a problem,the value is out of range
my_func(10)
# this one works,as expected,no hints
my_func(Int0To9(2))
# this one raises an AssertionError,before the function is even called,as the Int0To9 cannot be instantiated
try:
my_func(Int0To9(11))
except AssertionError:
print('error,as expected (11)')
def my_safe_func(x: int):
assert x in range(10)
print(x)
# no problem
my_safe_func(3)
# This now raises an assertion error as well
try:
my_safe_func(12)
except AssertionError:
print('error,as expected (12)')
# no problem here still
my_safe_func(Int0To9(4))
def my_very_safe_func(x: Int0To9):
assert x in range(10)
print(x)
# this one gives a type hint and fails correctly
try:
my_very_safe_func(13)
except AssertionError:
print('error,as expected (13)')
# this one gives a type hint but succeeds if you run it,as expected
my_very_safe_func(5)
# only this one runs correctly without hints
my_very_safe_func(Int0To9(6))
# this one also fails,as before
try:
my_very_safe_func(Int0To9(14))
except AssertionError:
print('error,as expected (14)')
结果:
1
10
2
error,as expected (11)
3
error,as expected (12)
4
error,as expected (13)
5
6
error,as expected (14)
,
TLDR:如果值很少,则使用Literal
,如果需要编程验证,则使用NewType
。
Literal
可以静态定义允许的值。
from typing import literal
def digit_name(digit: Literal[0,1,2,3,4,5,6,7,8,9]) -> str: ...
digit_name(6) # valid
digit_name(12) # invalid
请注意,虽然Literal
从技术上仅表示这些值,但各种类型检查器的确仅允许这些值的实际文字。
NewType
是一种类型的低开销专业化。与用于在运行时检查类型以拒绝无效值的网守一起使用。
from typing import NewType
# Digit is a plain `int` at runtime,but a subclass for type checking
Digit = NewType('Digit',int)
def assert_digit(candidate: int) -> Digit:
assert 0 <= candidate <= 9 # assert can be optimised away with `-O` if the program is known to be correct
return Digit(candidate)
def digit_name(digit: Digit) -> str: ...
a_digit = assert_digit(3)
print(a_digit,'is',digit_name(a_digit)) # valid
print(a_digit,'is still',digit_name(a_digit)) # valid
print(3,'is also still',digit_name(3)) # invalid
此模式允许在“任何值”和“已验证值”之间建立边界。虽然必须明确调用网守并执行运行时检查,但静态类型检查可确保必须调用网守 ,但一次就足够了。
,一种方法是使用文档字符串,因此当用户键入help(function)时,他可以看到您用文档字符串编写的内容。
示例
def function(param : int)-> str:
"""
This function does this and returns this
:param param: integer with a maximum of 100
:return: anything
"""
# do something
# return value
所以当用户键入
help(function)
他会看到这样的帮助消息:
Help on function function in module __main__:
function(param: int) -> str
This function does this and returns this
:param param: integer with a maximum of 100
:return: anything
(END)
注意
如果用户在Pycharm中使用该功能(我不知道它在其他编辑器中是否起作用),则只能将鼠标悬停在该功能的名称上才能看到帮助菜单。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。