web-dev-qa-db-fra.com

Moyen approprié pour affirmer le type de variable dans Python

En utilisant une fonction, je souhaite m'assurer que le type des variables est comme prévu. Comment bien faire?

Voici un exemple de fausse fonction essayant de faire exactement cela avant de continuer avec son rôle:

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

Affirmez-vous la bonne approche? Dois-je utiliser try/except à la place?

De plus, mon ensemble de tests d'affirmation ne semble pas fonctionner correctement: S

Merci pythoneers

56
Morlock

Le isinstance intégré est le moyen préféré si vous devez vraiment, mais encore mieux est de se souvenir de la devise de Python: "il est plus facile de demander pardon que permission"! -) (C'était en fait la devise préférée de Grace Murray Hopper ;-). C'est à dire.:

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

Cela, BTW, permet à la fonction de fonctionner très bien sur les chaînes Unicode - sans aucun effort supplémentaire! -)

52
Alex Martelli

Vous voudrez peut-être essayer cet exemple pour la version 2.6 de 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()

Cependant, avez-vous envisagé de laisser la fonction échouer naturellement à la place?

12
Noctis Skytower

Faire type('') est effectivement équivalent à str et types.StringType

donc type('') == str == types.StringType sera évalué à "True"

Notez que les chaînes Unicode qui ne contiennent que ASCII échouent si la vérification des types de cette manière, vous pouvez donc vouloir faire quelque chose comme assert type(s) in (str, unicode) ou assert isinstance(obj, basestring), ce dernier a été suggéré dans les commentaires par 007Brendan et est probablement préféré.

isinstance() est utile si vous voulez demander si un objet est une instance d'une classe, par exemple:

class MyClass: pass

print isinstance(MyClass(), MyClass) # -> True
print isinstance(MyClass, MyClass()) # -> TypeError exception

Mais pour les types de base, par exemple str, unicode, int, float, long etc demander type(var) == TYPE fonctionnera bien.

7
cryo