在Python中断言变量类型的正确方法

时间:2010-04-07 01:51:11

标签: python testing assert

在使用函数时,我希望确保变量的类型符合预期。怎么做对了?

这是一个假冒函数示例,在继续其角色之前尝试这样做:

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

4 个答案:

答案 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('')实际上等同于strtypes.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

但对于基本类型,例如strunicodeintfloatlong等提问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() 不同的是,它实际上并不进行类型检查,因此您必须在必要时自己检查所有的键和值。

(我意识到这不完全是您所要求的,但是“类型断言”也用于此类事情,因此我避免了另一个会因重复而被关闭的问题。)