Frage

Ich weiß, dass python eine len() Funktion, die ist verwendet zu bestimmen die Größe der Zeichenfolge, aber ich Frage mich, warum es nicht eine Methode des string-Objekts.

Update

Ok, ich merkte, ich war peinlich, der Irrt. __len__() ist tatsächlich eine Methode des string-Objekts.Es scheint nur seltsam zu sehen, objektorientierten code in Python mit der len-Funktion auf string-Objekte.Darüber hinaus, es ist auch seltsam zu sehen, __len__ wie der name statt einfach nur len.

War es hilfreich?

Lösung

Strings haben eine Länge Methode haben: __len__()

Das Protokoll in Python ist diese Methode auf Objekte zu implementieren, die eine Länge haben, und verwenden Sie die eingebaute in len() -Funktion, die es für Sie, ähnlich wie nennt man __iter__() und die eingebaut in iter() Funktion (oder hat die Methode aufgerufen implementieren würde hinter den Kulissen für Sie) auf Objekte, die iterable sind.

Siehe emulieren Containertypen für weitere Informationen .

Hier ist ein gutes Buch zum Thema Protokolle in Python: Python und das Prinzip des kleinsten Astonishment

Andere Tipps

Jims Antwort href="https://stackoverflow.com/questions/83983/why-isnt-the-len-function-inherited-by-dictionaries-and-lists-in-python"> diese Frage kann helfen; Ich kopiere es hier. Guido van Rossum Zitiert:

  

Zunächst einmal habe ich len (x) über x.len () für HCI Gründen (def __len __ () kam viel später). Es gibt zwei ineinander verschlungene Gründe tatsächlich, beide HCI:

     

(a) Für einige Operationen, Präfixnotation liest einfach besser als postfix - (! Und Infix) Präfixoperationen eine lange Tradition in der Mathematik hat, die Notationen mag, wo das Visuals den Mathematiker hilft über ein Problem nachzudenken. Vergleichen Sie die einfach, mit dem wir eine Formel wie x * umschreiben (a + b) in x a + x b auf die Ungeschicklichkeit das gleiche tun eine rohe OO-Notation.

     

(b) Wenn ich Code gelesen, die besagt, len (x) Ich weiß, dass es für die Länge von etwas zu fragen. Das sagt mir zwei Dinge: das Ergebnis ist eine ganze Zahl, und das Argument ist eine Art Behälter. Im Gegenteil, wenn ich x.len () lese, muß ich schon, dass x weiß, ist eine Art von Behälter, der eine Schnittstelle oder erbt von einer Klasse implementieren, die eine Standard-len haben (). Erleben Sie die Verwirrung wir gelegentlich, wenn eine Klasse, die nicht implementiert eine Abbildung eines get hat () oder Tasten () -Methode, oder etwas, das nicht eine Datei ist, hat eine Methode write ().

     

Zu sagen, die gleiche Sache in einer anderen Art und Weise, ich ‚len‘ als Einbau in Betrieb zu sehen. Ich würde es hassen, dass zu verlieren. / ... /

Es gibt eine len Methode:

>>> a = 'a string of some length'
>>> a.__len__()
23
>>> a.__len__
<method-wrapper '__len__' of str object at 0x02005650>

Python ist eine pragmatische Programmiersprache, und die Gründe für len() eine Funktion und kein Verfahren von str sein, list, dict usw. sind pragmatisch.

Die len() eingebaute Funktion direkt mit dem eingebauten Typen: die CPython Implementierung von len() tatsächlich gibt den Wert des ob_size Feldes in dem PyVarObject C struct , die jede mit variabler Größe Einbau-Objekt im Speicher darstellt. Dies ist viel schneller als der Aufruf einer Methode - kein Attribut-Lookup muss geschehen. Immer die Anzahl der Elemente in einer Sammlung ist ein gemeinsamer Betrieb und müssen effizient für eine solche grundlegende und vielfältige Arten wie str, list, array.array usw. arbeiten

Allerdings Förderung der Kohärenz, wenn len(o) zu einem benutzerdefinierten Typ Anwendung, ruft Python o.__len__() als Ausweich. __len__, __abs__ und alle anderen in der Python Data Model machen es einfach Objekte zu erstellen, verhalten sich wie die Einbauten, so dass die ausdrucksstark und sehr konsistent APIs wir „Pythonic“ nennen.

Durch die Implementierung von speziellen Methoden, um Ihre Objekte können Iteration unterstützen, Überlast- Infixoperatoren, verwalten Kontexte in with Blöcke usw. Sie des Datenmodells als eine Möglichkeit denken können die Python-Sprache verwenden, sich als Rahmen wo die Objekte, die Sie erstellen können nahtlos integriert werden.

Ein zweiter Grund, durch Zitate von Guido van Rossum wie diese , ist, dass es einfacher ist, als len(s) s.len() zu lesen und schreiben.

Die Notation len(s) steht im Einklang mit unäre Operatoren mit Präfixnotation, wie abs(n). len() ist viel häufiger als abs() verwendet, und es verdient so einfach zu schreiben.

Es kann auch einen historischen Grund: in der ABC-Sprache, den Python voraus (und war sehr einflussreich in seinem Design) gab es einen unärer Operator als #s geschrieben, die len(s) gemeint

.
met% python -c 'import this' | grep 'only one'
There should be one-- and preferably only one --obvious way to do it.

Es gibt einige gute Antworten hier, und so bevor ich meine eigenen ich möchte zu markieren ein paar der Edelsteine (keine ruby Wortspiel beabsichtigt) habe ich hier gelesen.

  • Python ist nicht eine pure OOP-Sprache-es ist eine Allgemeine-Zweck, multi-Paradigma-Sprache, die der Programmierer verwenden das Paradigma, die Sie am meisten bequem mit und/oder Paradigma, dass ist am besten geeignet für Ihre Lösung.
  • Python hat erste-Klasse Funktionen, so len ist eigentlich ein Objekt.Ruby, auf der anderen Seite, nicht first-class-Funktionen.So die len Funktion Objekt hat seine eigenen Methoden, die können Sie überprüfen, indem Sie ausführen dir(len).

Wenn Sie nicht wie die Art und Weise dies funktioniert in Ihrem eigenen code, es ist trivial für Sie zu re-implementieren Sie den Behälter mithilfe Ihrer bevorzugten Methode (siehe Beispiel unten).

>>> class List(list):
...     def len(self):
...         return len(self)
...
>>> class Dict(dict):
...     def len(self):
...         return len(self)
...
>>> class Tuple(tuple):
...     def len(self):
...         return len(self)
...
>>> class Set(set):
...     def len(self):
...         return len(self)
...
>>> my_list = List([1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F'])
>>> my_dict = Dict({'key': 'value', 'site': 'stackoverflow'})
>>> my_set = Set({1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F'})
>>> my_tuple = Tuple((1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F'))
>>> my_containers = Tuple((my_list, my_dict, my_set, my_tuple))
>>>
>>> for container in my_containers:
...     print container.len()
...
15
2
15
15

Sie können auch sagen,

>> x = 'test'
>> len(x)
4

Mit Python 2.7.3.

oder nicht?

>>> "abc".__len__()
3
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top