Bei der Verwendung einer Funktion möchte ich sicherstellen, dass der Typ der Variablen wie erwartet ist. Wie mache ich es richtig?
Hier ist ein Beispiel für eine gefälschte Funktion, die versucht, genau dies zu tun, bevor sie mit ihrer Rolle fortfährt:
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()
Ist die Behauptung der richtige Ansatz? Soll ich stattdessen try / exception verwenden?
Außerdem scheint meine Testreihe nicht richtig zu funktionieren: S.
Danke Pythononeer
typing
Moduls in Python 3.6, Mypy und anderen Tools gilt die obige Aussage so: Es wäre großartig, eine statisch typisierte Version von Python zu haben.Antworten:
Das
isinstance
Eingebaute ist der bevorzugte Weg, wenn Sie es wirklich müssen, aber noch besser ist es, sich an Pythons Motto zu erinnern: "Es ist einfacher, um Vergebung zu bitten als um Erlaubnis"! -) (Es war eigentlich Grace Murray Hoppers Lieblingsmotto ;-). Dh: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')
Übrigens, damit funktioniert die Funktion auch bei Unicode-Strings einwandfrei - ohne zusätzlichen Aufwand! -)
quelle
assert
Dies ist manchmal nützlich für Überprüfungen der Integrität, die Sie nur in der Entwicklungsphase benötigen (nicht in optimiertem Produktionscode, wo er wegoptimiert wird). Überprüfen Sie daher keine gültigen Eingaben (die Sie anderweitig ausführen müssen), sondern die Überprüfung der Integrität selbst Logik (Schleifenvarianten, Klasseninvarianten usw.) - natürlich nicht typbezogen. Das Testframework von Drittanbietern py.test verwendetassert
die Art und Weise, wie der Standardunittest
Methoden wieassertEqual
& c verwendet.lower()
,upper()
und__add__()
Methoden. Dies wird als Ententypisierung bezeichnet (es sieht aus wie eine Ente und spricht wie eine Ente (hat die gleichen Methoden), auch wenn es wirklich überhaupt keine Ente ist), und es ist die bevorzugte Methode für Python. Wenn Sie eine Ausnahme auslösen möchten, weil die übergebenen Argumente vom falschen Typ waren, sollten Sie eine auslösenTypeError
.Vielleicht möchten Sie dieses Beispiel für Version 2.6 von Python ausprobieren.
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()
Haben Sie jedoch darüber nachgedacht, die Funktion stattdessen auf natürliche Weise ausfallen zu lassen?
quelle
Tun
type('')
ist effektiv gleichbedeutend mitstr
undtypes.StringType
so
type('') == str == types.StringType
wird zu "True
" auswertenBeachten Sie, dass Unicode-Zeichenfolgen, die nur ASCII enthalten, fehlschlagen, wenn Typen auf diese Weise überprüft werden. Daher möchten Sie möglicherweise etwas wie
assert type(s) in (str, unicode)
oder tunassert isinstance(obj, basestring)
, wobei letzteres in den Kommentaren von 007Brendan vorgeschlagen wurde und wahrscheinlich bevorzugt wird.isinstance()
ist nützlich, wenn Sie fragen möchten, ob ein Objekt eine Instanz einer Klasse ist, z.class MyClass: pass print isinstance(MyClass(), MyClass) # -> True print isinstance(MyClass, MyClass()) # -> TypeError exception
Aber für Grundtypen, zum Beispiel
str
,unicode
,int
,float
,long
usw. fragentype(var) == TYPE
Wille Arbeit OK.quelle