Правильный способ утверждать тип переменной в Python - PullRequest
55 голосов
/ 07 апреля 2010

При использовании функции я хочу убедиться, что тип переменных соответствует ожидаемому. Как это сделать правильно?

Вот пример фальшивой функции, пытающейся сделать это перед продолжением своей роли:

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 не работает должным образом: S

Спасибо питонерам

Ответы [ 3 ]

52 голосов
/ 07 апреля 2010

Встроенный isinstance является предпочтительным способом, если вам действительно нужно, но еще лучше запомнить девиз Python: «Проще просить прощения, чем разрешения»! -) (Это было на самом деле Любимый девиз Грейс Мюррей Хоппер ;-). I.e.:

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 - без каких-либо дополнительных усилий! -)

12 голосов
/ 07 апреля 2010

Возможно, вы захотите попробовать этот пример для версии 2.6 Python.

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

Однако, вы рассматривали возможность естественного сбоя функции вместо этого?

7 голосов
/ 07 апреля 2010

Doing type('') фактически эквивалентно str и types.StringType

поэтому type('') == str == types.StringType будет оцениваться как "True"

Обратите внимание, что строки Unicode, содержащие только ASCII, не будут работать при проверке типов таким образом, поэтому вы можете захотеть сделать что-то вроде 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 будет работать нормально.

...