2016-09-08 3 views
1

Ich habe eine (vereinfachte) -Modul, so etwas wie dieses:Mit Bezug auf äußere Umfang von Python-Klasse

import tkinter as tk 

__outerVar = {<dict stuff>} 

class Editor(tk.Frame): 
... 
    def _insideFunction(self): 
     for p in __outerVar.keys(): 
      <do stuff> 

Ich erhalte eine NameError: name '_Editor__outerVar' is not defined über die Verwendung von __outerVar, wenn ich versuche Editor zu instanziiert. Ich habe versucht, "global __outerVar" oben auf insideFunction, obwohl ich nicht auf __outerVar schreibe, gleichen Fehler.

Ich bin mir sicher, dass ich hier nur eine Python-Scope-Regel falsch verstehe. Hilfe?

py 3,5

+0

Python Name Mangling bei der Arbeit. Warum nicht nur "äußereVar" und in deiner Klasse als "äußereVar" aufrufen? –

+0

Ich dachte, die _ und __ waren nur Konvention, im Wesentlichen, geschützte und private Variablen. Ich war mir des Namens Mangling nicht bewusst. – Marc

Antwort

3

Python ersetzt alle Namen mit einem doppelten Unterstrich __, um 'private attributes' zu simulieren. Im Wesentlichen __name wird _classname__name. Dies rief Namen Mangeln, geschieht nur innerhalb von Klassen wie dokumentiert in the docs:

Diese Mangeln ohne Rücksicht auf die syntaktische Position der Kennung erfolgt, solange es innerhalb der Definition einer Klasse erfolgt.

Die Lösung ist keine __name Namen nicht verwenden, so etwas wie _name oder nur name genügt verwenden.

Als Nachtrag, in PEP 8 -- Method Names and Instance Variables heißt es:

Python mangles diese Namen mit dem Klassennamen: wenn Klasse Foo hat ein Attribut __a genannt, kann es nicht durch Foo.__a zugegriffen werden. (Ein eindringlicher Benutzer könnte immer noch Zugriff erhalten, wenn er Foo._Foo__a aufruft.) Im Allgemeinen sollten doppelte führende Unterstriche nur verwendet werden, um Namenskonflikte mit Attributen in Klassen zu vermeiden, die für Unterklassen bestimmt sind.

Also, wenn Sie für die Fälle sind der Gestaltung waren Unterklasse Name Klirren Problem sein könnte, nicht doppelt führenden Unterstrichen verwenden.

3

Sie Namen in der Tat Mangeln zu sehen. Von der documentation:

Jede Kennung der Form __spam (mindestens zwei führenden Unterstrichen, höchstens ein nachlaufStrich) textlich mit _classname__spam ersetzt wird, in dem Klassennamen der aktuellen Klassennamen mit führenden Unterstrich ist (n) abgezogen. Dieses Mangeln erfolgt ohne Berücksichtigung der syntaktischen Position des Bezeichners, solange es innerhalb der Definition einer Klasse auftritt.

Soweit ich denken kann, ist der einzige Weg, um dies ist es, die __outerVar im globalen Bereich zu etwas benennen, die nicht mit doppelten Unterstrichen beginnen.