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

104 投票
4 回答
217386 浏览
提问于 2025-04-15 21:19

在使用一个函数的时候,我想确保变量的类型是我预期的那样。该怎么做才对呢?

这里有一个假设的函数示例,试图在继续执行之前检查变量类型:

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()

使用assert(断言)是正确的方法吗?我应该用try/except(异常处理)来代替吗?

另外,我的断言测试似乎也没有正常工作 :S

谢谢大家,Python爱好者们

4 个回答

12

使用 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

但是对于基本类型,比如 strunicodeintfloatlong 等,使用 type(var) == TYPE 也是可以的。

28

你可以试试这个例子,适用于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() + text.upper() + end.lower()

不过,你有没有想过让这个函数自然地失败呢?

83

isinstance 是 Python 中一个内置的函数,如果你真的需要检查一个变量的类型,使用它是比较推荐的。不过,更好的做法是记住 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')

顺便提一下,这样做让这个函数在处理 Unicode 字符串时也能很好地工作——而且不需要额外的努力!-)

撰写回答