在使用函数时,我希望确保变量的类型符合预期。怎么做对了?
这是一个假冒函数示例,在继续其角色之前尝试这样做:
def my_print(begin, text, end):
"""Print 'text' in UPPER between 'begin' and 'end' in lower
"""
for i in (begin, text, end):
assert isinstance(i, str), "Input variables should be strings"
out = begin.lower() + text.upper() + end.lower()
print out
def test():
"""Put your test cases here!
"""
assert my_print("asdf", "fssfpoie", "fsodf")
assert not my_print("fasdf", 33, "adfas")
print "All tests passed"
test()
断言是正确的做法吗?我应该使用try / except吗?
此外,我的断言测试集似乎无法正常工作:S
谢谢pythoneers
答案 0 :(得分:51)
isinstance
内置是首选的方式,但更好的是要记住Python的座右铭:“请求宽恕比允许更容易”! - )(实际上是Grace Murray Hopper的最爱座右铭;-)。即:
def my_print(text, begin, end):
"Print 'text' in UPPER between 'begin' and 'end' in lower"
try:
print begin.lower() + text.upper() + end.lower()
except (AttributeError, TypeError):
raise AssertionError('Input variables should be strings')
这个,BTW,让函数在Unicode字符串上运行得很好 - 无需任何额外的努力! - )
答案 1 :(得分:11)
您可能希望在Python 2.6版本中尝试此示例。
def my_print(text, begin, end):
"Print text in UPPER between 'begin' and 'end' in lower."
for obj in (text, begin, end):
assert isinstance(obj, str), 'Argument of wrong type!'
print begin.lower() + begin.upper() + end.lower()
但是,您是否考虑过让这个功能自然失败?
答案 2 :(得分:7)
执行type('')
实际上等同于str
和types.StringType
因此type('') == str == types.StringType
将评估为“True
”
请注意,如果以这种方式检查类型,只包含ASCII的Unicode字符串将失败,因此您可能希望执行assert type(s) in (str, unicode)
或assert isinstance(obj, basestring)
之类的操作,后者在评论中建议007Brendan,可能是首选。
isinstance()
很有用,例如:
class MyClass: pass
print isinstance(MyClass(), MyClass) # -> True
print isinstance(MyClass, MyClass()) # -> TypeError exception
但对于基本类型,例如str
,unicode
,int
,float
,long
等提问type(var) == TYPE
即可。
答案 3 :(得分:0)
isinstance(x, str)
如果您可以使用它是最好的,但它不适用于泛型。例如你不能这样做:
isinstance(x, dict[str, int])
它会给出运行时错误:
TypeError: isinstance() argument 2 cannot be a parameterized generic
相反,您可以使用 cast
:
from typing import cast
x_as_dict = cast(dict[str, int], x)
当然,与 isinstance()
不同的是,它实际上并不进行类型检查,因此您必须在必要时自己检查所有的键和值。
(我意识到这不完全是您所要求的,但是“类型断言”也用于此类事情,因此我避免了另一个会因重复而被关闭的问题。)