Ist Python stark typisiert?

234

Ich bin auf Links gestoßen, die besagen, dass Python eine stark typisierte Sprache ist.

Ich dachte jedoch, in stark typisierten Sprachen könnte man das nicht tun:

bob = 1
bob = "bob"

Ich dachte, eine stark typisierte Sprache würde eine Typänderung zur Laufzeit nicht akzeptieren. Vielleicht habe ich eine falsche (oder zu vereinfachte) Definition von starken / schwachen Typen.

Ist Python eine stark oder schwach typisierte Sprache?

Pacane
quelle

Antworten:

358

Python ist stark dynamisch typisiert.

  • Starke Typisierung bedeutet, dass sich der Typ eines Werts nicht auf unerwartete Weise ändert. Eine Zeichenfolge, die nur Ziffern enthält, wird nicht auf magische Weise zu einer Zahl, wie dies in Perl der Fall sein kann. Jede Änderung des Typs erfordert eine explizite Konvertierung.
  • Dynamische Typisierung bedeutet, dass Laufzeitobjekte (Werte) einen Typ haben, im Gegensatz zur statischen Typisierung, bei der Variablen einen Typ haben.

Wie für Ihr Beispiel

bob = 1
bob = "bob"

Dies funktioniert, weil die Variable keinen Typ hat. es kann jedes Objekt benennen. Danach bob=1werden Sie feststellen, dass es type(bob)zurückkehrt int, aber danach bob="bob"kehrt es zurück str. (Beachten Sie, dass dies typeeine reguläre Funktion ist. Daher wertet sie das Argument aus und gibt dann den Typ des Werts zurück.)

Vergleichen Sie dies mit älteren Dialekten von C, die schwach und statisch typisiert waren, so dass Zeiger und ganze Zahlen ziemlich austauschbar waren. (Modernes ISO C erfordert in vielen Fällen Konvertierungen, aber mein Compiler ist diesbezüglich standardmäßig nachsichtig.)

Ich muss hinzufügen, dass die starke oder schwache Typisierung eher ein Kontinuum als eine boolesche Wahl ist. C ++ hat eine stärkere Typisierung als C (mehr Konvertierungen erforderlich), aber das Typsystem kann mithilfe von Zeigerumwandlungen untergraben werden.

Die Stärke des Typsystems in einer dynamischen Sprache wie Python hängt wirklich davon ab, wie seine Grundelemente und Bibliotheksfunktionen auf verschiedene Typen reagieren. ZB +ist überladen, so dass es mit zwei Zahlen oder zwei Zeichenfolgen funktioniert , aber nicht mit einer Zeichenfolge und einer Zahl. Dies ist eine Designentscheidung, die bei +der Implementierung getroffen wurde, aber nicht wirklich eine Notwendigkeit, die sich aus der Semantik der Sprache ergibt. Wenn Sie +einen benutzerdefinierten Typ überladen , können Sie ihn implizit in eine Zahl konvertieren lassen:

def to_number(x):
    """Try to convert function argument to float-type object."""
    try: 
        return float(x) 
    except (TypeError, ValueError): 
        return 0 

class Foo:
    def __init__(self, number): 
        self.number = number

    def __add__(self, other):
        return self.number + to_number(other)

Eine Klasseninstanz Fookann anderen Objekten hinzugefügt werden:

>>> a = Foo(42)
>>> a + "1"
43.0
>>> a + Foo
42
>>> a + 1
43.0
>>> a + None
42

Beachten Sie, dass Python, obwohl es stark typisiert ist, völlig in Ordnung ist, Objekte vom Typ intund hinzuzufügen, floatund ein Objekt vom Typ zurückgibt float(z . B. int(42) + float(1)Rückgaben 43.0). Andererseits würde sich Haskell aufgrund der Nichtübereinstimmung zwischen den Typen beschweren, wenn man Folgendes versucht (42 :: Integer) + (1 :: Float). Dies macht Haskell zu einer streng typisierten Sprache, in der Typen völlig unzusammenhängend sind und nur eine kontrollierte Form der Überladung über Typklassen möglich ist.

Fred Foo
quelle
18
Ein Beispiel, das ich nicht sehr oft sehe, aber ich denke, es ist wichtig zu zeigen, dass Python nicht vollständig stark typisiert ist, sondern all die Dinge, die sich als boolesch auswerten: docs.python.org/release/2.5.2/lib/truth.html
Gsingh2011
25
Ich bin mir nicht sicher, ob dies ein Gegenbeispiel ist: Dinge können zu einem Booleschen Wert ausgewertet werden, aber sie werden nicht plötzlich zu einem Booleschen Wert. Es ist fast so, als hätte jemand implizit so etwas wie as_boolean (<Wert>) aufgerufen, was nicht mit dem Typ des sich ändernden Objekts identisch ist, oder?
Jbrendel
15
Wahrhaftigkeit im booleschen Kontext ist kein Gegenbeispiel, weil nichts tatsächlich in Trueoder umgewandelt wird False. Aber was ist mit Nummernwerbung? 1.0 + 2funktioniert in Python genauso gut wie in Perl oder C, obwohl "1.0" + 2dies nicht der Fall ist. Ich stimme @jbrendel zu, dass dies keine implizite Konvertierung ist, sondern nur eine Überladung - aber im gleichen Sinne führt Perl auch keine implizite Konvertierung durch. Wenn Funktionen keine deklarierten Parametertypen haben, können implizite Konvertierungen nirgendwo stattfinden.
Abarnert
13
Eine bessere Möglichkeit, über eine starke Typisierung nachzudenken, besteht darin, dass der Typ wichtig ist, wenn Operationen an einer Variablen ausgeführt werden. Wenn der Typ nicht wie erwartet ist, ist eine Sprache, die sich beschwert, stark typisiert (Python / Java) und eine Sprache, die nicht schwach typisiert ist (Javascript). Dynamisch typisierte Sprachen (Python) sind solche, bei denen sich der Typ einer Variablen ändern kann Laufzeit, während statisch typisierte Sprachen (Java) dies nicht zulassen, sobald eine Variable deklariert ist.
Kashif
2
@ gsingh2011 Wahrhaftigkeit ist nützlich und keine schwache Eingabe für sich, aber ein versehentliches if isValid(value) - 1kann auslaufen. Der Boolesche Wert wird in eine Ganzzahl umgewandelt, die dann als wahrheitsgemäßer Wert ausgewertet wird. False - 1wird wahr und True - 1falsch, was zu einem peinlich schwierigen zweischichtigen Fehler beim Debuggen führt. In diesem Sinne ist Python meist stark typisiert; Typzwänge verursachen normalerweise keine logischen Fehler.
Aaron3468
57

Es gibt einige wichtige Punkte, die meiner Meinung nach alle vorhandenen Antworten übersehen haben.


Schwache Eingabe bedeutet, den Zugriff auf die zugrunde liegende Darstellung zu ermöglichen. In C kann ich einen Zeiger auf Zeichen erstellen und dann dem Compiler mitteilen, dass ich ihn als Zeiger auf Ganzzahlen verwenden möchte:

char sz[] = "abcdefg";
int *i = (int *)sz;

Auf einer Little-Endian-Plattform mit 32-Bit-Ganzzahlen wird daraus iein Array der Zahlen 0x64636261und 0x00676665. Sie können sogar selbst Zeiger auf Ganzzahlen (der entsprechenden Größe) umwandeln:

intptr_t i = (intptr_t)&sz;

Und das bedeutet natürlich, dass ich Speicher überall im System überschreiben kann. *

char *spam = (char *)0x12345678
spam[0] = 0;

* Natürlich verwenden moderne Betriebssysteme virtuellen Speicher und Seitenschutz, sodass ich nur den Speicher meines eigenen Prozesses überschreiben kann, aber nichts an C selbst bietet einen solchen Schutz, wie jeder, der jemals beispielsweise auf Classic Mac OS oder Win16 codiert hat, Ihnen sagen kann.

Traditionelles Lisp erlaubte ähnliche Arten von Hackerangriffen; Auf einigen Plattformen waren Doppelwort-Floats und Cons-Zellen vom gleichen Typ, und Sie konnten einfach eine an eine Funktion übergeben, die die andere erwartet, und es würde "funktionieren".

Die meisten Sprachen sind heute nicht ganz so schwach wie C und Lisp, aber viele von ihnen sind immer noch etwas undicht. Zum Beispiel jede OO-Sprache mit einem ungeprüften "Downcast" *, das ein Typleck ist: Sie sagen dem Compiler im Wesentlichen: "Ich weiß, ich habe Ihnen nicht genügend Informationen gegeben, um zu wissen, dass dies sicher ist, aber ich bin mir ziemlich sicher es ist, "wenn der springende Punkt eines Typsystems ist, dass der Compiler immer genug Informationen hat, um zu wissen, was sicher ist.

* Ein überprüfter Downcast macht das Typensystem der Sprache nicht schwächer, nur weil die Prüfung auf Laufzeit verschoben wird. Wenn dies der Fall wäre, wäre der Subtyp-Polymorphismus (auch bekannt als virtuelle oder volldynamische Funktionsaufrufe) dieselbe Verletzung des Typsystems, und ich glaube, niemand möchte das sagen.

Sehr wenige "Skriptsprachen" sind in diesem Sinne schwach. Selbst in Perl oder Tcl können Sie einen String nicht nehmen und seine Bytes nur als Ganzzahl interpretieren. * Aber es ist erwähnenswert, dass Sie in CPython (und ähnlich für viele andere Interpreter für viele Sprachen) wirklich hartnäckig sind kann verwendet ctypeswerden libpython, um ein Objekt zu laden , auf ein Objekt idzu werfen POINTER(Py_Object)und das Typsystem zum Auslaufen zu zwingen. Ob dies das Typsystem schwach macht oder nicht, hängt von Ihren Anwendungsfällen ab. Wenn Sie versuchen, eine Sandbox mit eingeschränkter Ausführung in der Sprache zu implementieren, um die Sicherheit zu gewährleisten, müssen Sie sich mit solchen Escape-Effekten auseinandersetzen.

* Sie können eine Funktion wie verwenden struct.unpack , um die Bytes zu lesen und ein neues int aus "wie C diese Bytes darstellen würde" zu erstellen, aber das ist offensichtlich nicht undicht; sogar Haskell erlaubt das.


In der Zwischenzeit unterscheidet sich die implizite Konvertierung wirklich von einem schwachen oder undichten System.

Jede Sprache, auch Haskell, hat Funktionen, um beispielsweise eine Ganzzahl in einen String oder ein Float umzuwandeln. Einige Sprachen führen einige dieser Konvertierungen jedoch automatisch für Sie durch, z. B. in C, wenn Sie eine Funktion aufrufen, die eine möchte float, und diese übergebenint , wird sie für Sie konvertiert. Dies kann definitiv zu Fehlern mit beispielsweise unerwarteten Überläufen führen, aber es handelt sich nicht um die gleichen Arten von Fehlern, die Sie von einem schwachen Typsystem erhalten. Und C ist hier nicht wirklich schwächer; Sie können in Haskell ein int und ein float hinzufügen oder sogar ein float zu einer Zeichenfolge verketten. Sie müssen dies nur expliziter tun.

Und mit dynamischen Sprachen ist das ziemlich trübe. In Python oder Perl gibt es keine "Funktion, die einen Float will". Es gibt jedoch überladene Funktionen, die unterschiedliche Aufgaben mit unterschiedlichen Typen ausführen, und es besteht ein starkes intuitives Gefühl, dass das Hinzufügen einer Zeichenfolge zu etwas anderem "eine Funktion ist, die eine Zeichenfolge möchte". In diesem Sinne scheinen Perl, Tcl und JavaScript viele implizite Konvertierungen durchzuführen ( "a" + 1gibt Ihnen "a1"), während Python viel weniger ausführt ( "a" + 1eine Ausnahme 1.0 + 1auslöst, Ihnen aber 2.0* gibt). Es ist nur schwer, diesen Sinn in formale Begriffe zu fassen - warum sollte es keine geben +, die einen String und ein Int benötigt, wenn es offensichtlich andere Funktionen wie die Indizierung gibt, die dies tun?

* Tatsächlich kann dies in modernem Python durch OO-Subtypisierung erklärt werden, da dies isinstance(2, numbers.Real)wahr ist. Ich glaube nicht, dass es in irgendeiner Weise 2eine Instanz des Stringtyps in Perl oder JavaScript gibt ... obwohl dies in Tcl tatsächlich der Fall ist, da alles eine Instanz eines Strings ist.


Schließlich gibt es noch eine andere, vollständig orthogonale Definition von "stark" vs. "schwach", wobei "stark" kraftvoll / flexibel / ausdrucksstark bedeutet.

Mit Haskell können Sie beispielsweise einen Typ definieren, der eine Zahl, eine Zeichenfolge, eine Liste dieses Typs oder eine Zuordnung von Zeichenfolgen zu diesem Typ ist. Dies ist eine perfekte Möglichkeit, alles darzustellen, was aus JSON dekodiert werden kann. Es gibt keine Möglichkeit, einen solchen Typ in Java zu definieren. Aber zumindest hat Java parametrische (generische) Typen, sodass Sie eine Funktion schreiben können, die eine Liste von T verwendet und weiß, dass die Elemente vom Typ T sind. Andere Sprachen, wie das frühe Java, haben Sie gezwungen, eine Liste von Objekten und Downcasts zu verwenden. Zumindest mit Java können Sie jedoch neue Typen mit eigenen Methoden erstellen. Mit C können Sie nur Strukturen erstellen. Und BCPL hatte das nicht einmal. Und so weiter bis zur Montage, wo die einzigen Typen unterschiedliche Bitlängen sind.

In diesem Sinne ist das Haskell-Typsystem stärker als das moderne Java, das stärker ist als das frühere Java, das stärker ist als das C, das stärker als das BCPL ist.

Wo passt Python in dieses Spektrum? Das ist ein bisschen schwierig. In vielen Fällen können Sie mit der Eingabe von Enten alles simulieren, was Sie in Haskell tun können, und sogar einige Dinge, die Sie nicht können. Sicher, Fehler werden zur Laufzeit anstatt zur Kompilierungszeit abgefangen, aber sie werden immer noch abgefangen. Es gibt jedoch Fälle, in denen das Tippen von Enten nicht ausreicht. In Haskell können Sie beispielsweise feststellen, dass eine leere Liste von Ints eine Liste von Ints ist, sodass Sie entscheiden können, dass das Reduzieren +über diese Liste 0 * zurückgeben soll. In Python ist eine leere Liste eine leere Liste. Es gibt keine Typinformationen, die Ihnen bei der Entscheidung helfen, was eine Reduzierung +bewirken soll.

* Tatsächlich lässt Haskell Sie dies nicht zu. Wenn Sie die Reduktionsfunktion aufrufen, die keinen Startwert für eine leere Liste annimmt, wird eine Fehlermeldung angezeigt. Aber seine Art System ist leistungsfähig genug , dass man könnte diese Arbeit machen, und Python ist es nicht.

abarnert
quelle
3
Diese Antwort ist brillant! Schade, dass es so lange am Ende der Liste gelitten hat.
LeoR
1
Nur ein kleiner Kommentar zu Ihrem C-Beispiel: Es char sz[]ist kein Zeiger auf char, sondern ein Array von char, und in der Zuweisung zerfällt es in einen Zeiger.
Majkel.mk
39

Sie verwechseln "stark typisiert" mit "dynamisch typisiert" .

Ich kann den Typ von nicht 1durch Hinzufügen der Zeichenfolge ändern '12', aber ich kann auswählen, welche Typen ich in einer Variablen speichere, und dies während der Laufzeit des Programms ändern.

Das Gegenteil von dynamischer Typisierung ist statische Typisierung. Die Deklaration von Variablentypen ändert sich während der Lebensdauer eines Programms nicht. Das Gegenteil von starkem Tippen ist schwaches Tippen; Die Art der Werte kann sich während der Lebensdauer eines Programms ändern.

Martijn Pieters
quelle
Die Beschreibung im Link ist stark typisiert: "Im Allgemeinen gelten für eine stark typisierte Sprache beim Kompilieren strengere Typisierungsregeln, was bedeutet, dass Fehler und Ausnahmen beim Kompilieren häufiger auftreten." impliziert, dass Python eine schwach typisierte Sprache ist ..., ist Wiki falsch?
Regen
1
@ s̮̦̩e̝͓c̮͔̞ṛ̖̖e̬̣̦t̸͉̥̳̼: das ist überhaupt nicht impliziert. Python hat zum Zeitpunkt der Kompilierung strenge Typisierungsregeln. Jedes erstellte Objekt hat nur einen Typ. Und "allgemein" bedeutet nichts, es bedeutet nur, dass Python eine Ausnahme davon ist.
Martijn Pieters
24

Laut diesem Wiki-Python- Artikel ist Python sowohl dynamisch als auch stark typisiert (bietet auch eine gute Erklärung).

Vielleicht denken Sie an statisch typisierte Sprachen, in denen sich die Typen während der Programmausführung nicht ändern können und die Typüberprüfung während der Kompilierungszeit erfolgt, um mögliche Fehler zu erkennen.

Diese SO-Frage könnte von Interesse sein: Dynamische Typensprachen im Vergleich zu statischen Typensprachen. Dieser Wikipedia-Artikel zu Typensystemen enthält weitere Informationen

Levon
quelle
18

TLDR;

Python gibt Dynamic ein, sodass Sie eine Zeichenfolgenvariable in eine int ändern können

x = 'somestring'
x = 50

Die Python-Eingabe ist stark, sodass Sie keine Typen zusammenführen können:

'foo' + 3 --> TypeError: cannot concatenate 'str' and 'int' objects

In schwach typisiertem Javascript passiert dies ...

 'foo'+3 = 'foo3'

In Bezug auf Typinferenz

Java zwingt Sie, Ihre Objekttypen explizit zu deklarieren

int x = 50

Kotlin verwendet Inferenz, um zu erkennen, dass es sich um eine handeltint

x = 50

Da jedoch beide Sprachen statische Typen verwenden, xkann diese nicht von einer geändert werden int. Keine der beiden Sprachen würde eine dynamische Veränderung zulassen

x = 50
x = 'now a string'
Adam Hughes
quelle
Ich kenne die Details von Javascript nicht, aber 'x' + 3möglicherweise operator+überladen und die Typkonvertierung hinter den Kulissen durchführen?
Regen
3
Wie auch immer, Ihre Antwort ist prägnanter und leichter zu verstehen als die oben genannten.
Regen
8

Es wurde bereits einige Male beantwortet, aber Python ist eine stark typisierte Sprache:

>>> x = 3
>>> y = '4'
>>> print(x+y)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'

Folgendes in JavaScript:

var x = 3    
var y = '4'
alert(x + y) //Produces "34"

Das ist der Unterschied zwischen schwacher und starker Eingabe. Schwache Typen versuchen automatisch, je nach Kontext (z. B. Perl) von einem Typ in einen anderen zu konvertieren. Starke Typen konvertieren niemals implizit.

Ihre Verwirrung liegt in einem Missverständnis darüber, wie Python Werte an Namen bindet (allgemein als Variablen bezeichnet).

In Python haben Namen keine Typen, sodass Sie Folgendes tun können:

bob = 1
bob = "bob"
bob = "An Ex-Parrot!"

Und Namen können an alles gebunden werden:

>>> def spam():
...     print("Spam, spam, spam, spam")
...
>>> spam_on_eggs = spam
>>> spam_on_eggs()
Spam, spam, spam, spam

Zur weiteren Lektüre:

https://en.wikipedia.org/wiki/Dynamic_dispatch

und die etwas verwandten, aber fortgeschritteneren:

http://effbot.org/zone/call-by-object.htm

Wayne Werner
quelle
1
Einige Jahre später - eine weitere nützliche und relevante Ressource: youtu.be/_AEJHKGk9ns
Wayne Werner
Starkes gegen schwaches Tippen hat nichts mit dem Ergebnistyp von Ausdrücken wie 3 + '4' zu tun. JavaScript ist in diesem Beispiel genauso stark wie Python.
QZNC
@qznc wie ist Javasript genauso stark? Ich glaube nicht, dass ich angedeutet habe, dass es irgendetwas mit dem resultierenden Typ zu tun hat, tatsächlich sage ich ausdrücklich, dass schwache Typen automatisch versuchen, von einem Typ in einen anderen zu konvertieren .
Wayne Werner
2
@oneloop das ist nicht unbedingt wahr, es ist nur so, dass das Verhalten beim Kombinieren von Floats und Ints genau definiert ist und zu einem Float führt. Sie können auch "3"*4in Python tun . Das Ergebnis ist natürlich "3333". Sie würden nicht sagen, dass es beides konvertiert. Das könnte natürlich nur eine Diskussion über die Semantik sein.
Wayne Werner
1
@oneloop Es ist nicht unbedingt wahr, dass Python floataus der Kombination von erzeugt floatund intden Typ implizit konvertiert. Es gibt eine natürliche Beziehung zwischen float und int, und tatsächlich formuliert die Typenerbarchie dies. Ich nehme an, Sie könnten argumentieren, dass Javascript genau definierte Operationen in Betracht zieht '3'+4und 'e'+4beide genau so definiert sind, wie Python es als 3.0 + 4gut definiert betrachtet, aber zu diesem Zeitpunkt gibt es wirklich keine starken oder schwachen Typen, nur (un) definierte Operationen.
Wayne Werner
6

Eine Python-Variable speichert einen untypisierten Verweis auf das Zielobjekt, das den Wert darstellt.

Jede Zuweisungsoperation bedeutet, dass die nicht typisierte Referenz dem zugewiesenen Objekt zugewiesen wird - dh das Objekt wird über die ursprüngliche und die neue (gezählte) Referenz geteilt.

Der Werttyp ist an das Zielobjekt gebunden, nicht an den Referenzwert. Die (starke) Typprüfung erfolgt, wenn eine Operation mit dem Wert ausgeführt wird (Laufzeit).

Mit anderen Worten, Variablen haben (technisch) keinen Typ - es ist nicht sinnvoll, in Form eines Variablentyps zu denken, wenn man genau sein will. Aber Referenzen werden automatisch dereferenziert und wir denken tatsächlich in Bezug auf den Typ des Zielobjekts.

pepr
quelle
6

Der Begriff "starke Typisierung" hat keine definitive Definition.

Daher hängt die Verwendung des Begriffs davon ab, mit wem Sie sprechen.

Ich betrachte keine Sprache, in der der Typ einer Variablen weder explizit deklariert noch statisch typisiert ist, als stark typisiert.

Starke Typisierung schließt nicht nur die Konvertierung aus (z. B. "automatische" Konvertierung von einer Ganzzahl in eine Zeichenfolge). Dies schließt eine Zuweisung aus (dh das Ändern des Typs einer Variablen).

Wenn der folgende Code kompiliert (interpretiert) wird, ist die Sprache nicht stark typisiert:

Foo = 1 Foo = "1"

In einer stark typisierten Sprache kann sich ein Programmierer auf einen Typ "verlassen".

Wenn beispielsweise ein Programmierer die Deklaration sieht,

UINT64 kZarkCount;

und er oder sie weiß, dass 20 Zeilen später kZarkCount immer noch ein UINT64 ist (solange es im selben Block vorkommt) - ohne den dazwischenliegenden Code untersuchen zu müssen.

user5330045
quelle
1

Ich habe gerade eine großartige, prägnante Möglichkeit entdeckt, sie auswendig zu lernen:

Dynamisch / statisch typisierte Exposition; stark / schwach typisierter Wert.

Regen
quelle
0

Ich denke, dieses einfache Beispiel sollte Ihnen die Unterschiede zwischen starker und dynamischer Typisierung erklären:

>>> tup = ('1', 1, .1)
>>> for item in tup:
...     type(item)
...
<type 'str'>
<type 'int'>
<type 'float'>
>>>

Java:

public static void main(String[] args) {
        int i = 1;
        i = "1"; //will be error
        i = '0.1'; // will be error
    }
Dmitry Zagorulkin
quelle
Ihr Python-Code demonstriert die dynamische Typisierung, während Java die statische Typisierung demonstriert. Ein besseres Beispiel wäre $ var = '2' + 1 // Ergebnis ist 3
erichlf
@ivleph Ich stimme zu. Es ist auch möglich, so etwas zu schreiben: "a" * 3 == "aaa"
Dmitry Zagorulkin
-4
class testme(object):
    ''' A test object '''
    def __init__(self):
        self.y = 0

def f(aTestMe1, aTestMe2):
    return aTestMe1.y + aTestMe2.y




c = testme            #get a variable to the class
c.x = 10              #add an attribute x inital value 10
c.y = 4               #change the default attribute value of y to 4

t = testme()          # declare t to be an instance object of testme
r = testme()          # declare r to be an instance object of testme

t.y = 6               # set t.y to a number
r.y = 7               # set r.y to a number

print(f(r,t))         # call function designed to operate on testme objects

r.y = "I am r.y"      # redefine r.y to be a string

print(f(r,t))         #POW!!!!  not good....

Das Obige würde in einem großen System über einen langen Zeitraum einen Albtraum von nicht wartbarem Code erzeugen. Nennen Sie es wie Sie wollen, aber die Fähigkeit, einen Variablentyp "dynamisch" zu ändern, ist nur eine schlechte Idee ...

Ryan Alexander
quelle