2016-04-16 4 views
2

Hallo, ich habe eine Klasse repräsentieren oder lokalen Kalender (außer AD) Hier möchte ich alle, die Klassenattribute gelesen werden nurPython-Klasse einzige Variable ohne ‚_‘ am Anfang des Namens

lesen
class BSDate(object): 

def __init__(self, year, month, date): 
    self._year = year 
    self._month = month 
    self._date = date 

In Python interpretor möchte ich Monat bekommen, damit ich so zu tun haben:

x = BSDate(2072,5,2) 
x._month 

aber ich möchte Monat erhalten, indem einfach

Aufruf
x.month 

Wie kann ich das lösen?

+0

['property'] (https://docs.python.org/2/library/functions.html # property) –

Antwort

3

können Sie @property verwenden, um eine Getter-Methode

@property 
def year(self): 
    return self._year 

@property 
def month(self): 
    return self._month 

@property 
def date(self): 
    return self._date 

Nun, wenn Sie Ihre Kundennummer sein kann, zu emulieren:

my_date = BSDate(y, m, d) 
month = my_date.month 
year = my_date.year 
date = my_date.date 

@property können auch Werte "nur lesen" zu erzwingen verwendet werden:

@property.setter 
def month(self, value): 
    raise AttributeError("This value is read only") 

Der Code wird einen Fehler verursachen, wenn der Client versucht zu ändern month

+1

Sie sollten den Fehler zeigen, wenn die Eigenschaft versucht wird geschrieben zu werden, beweisen, dass es nur gelesen wird, auch einen Link zu [der Dokumentation] (https://docs.python.org/2/library/functions .html # Eigenschaft) wäre nett. –

+0

Auch ich kann den Wert von ** x._month = 2 ** festlegen. Ich nehme an, ** _ Monat ** sollte geschützt werden. – wrufesh

+0

Gute Punkte TMDJ, ich habe meine Antwort geändert, um Ihre Vorschläge hinzuzufügen. –

2

In Python sollten Sie sich nicht wirklich um private Eigenschaften kümmern, die empfohlene Vorgehensweise besteht darin, einfach nur Attribute zu verwenden und Eigenschaften nur dann zu verwenden, wenn Sie Einschränkungen für Zuordnungen oder berechnete Werte erzwingen müssen. Pythons Philosophie ist, dass "wir alle Erwachsenen zustimmen" und man sollte die Dinge nicht komplizierter machen, als sie sein müssten. Ich würde einfach Attribute verwenden, bis Sie einen starken Grund haben, etwas Komplizierteres zu verwenden.

4
class BSDate(object): 
    def __init__(self, year, month, date): 
     self._year = year 
     self._month = month 
     self._date = date 

    @property 
    def month(self): 
     return self._month 

Sie können es dabei belassen, wie Sie jetzt obj.month darauf zugreifen können und es wirft AttributeError wenn jemand obj.month = val versucht. Wenn Sie den Benutzer jedoch zur Laufzeit über dieses Verhalten informieren und/oder die Fehlermeldung informativer gestalten möchten, implementieren Sie den entsprechenden Setter wie folgt.

@property.setter 
    def month(self, value): 
     # self._month = value if you want to set 
     raise AttributeError("Very good error message") 
     # or just print to terminal that can't set and go ahead 
0

In Python gibt es keine Möglichkeit, eine echte schreibgeschützte Eigenschaft auszuführen. Sie können jedoch, wie andere bereits erwähnt haben, eine Funktion mit einem property Decorator deklarieren. Sie könnten auch die Setter-Funktion über def __setattr__(self, key, value):

0

überladen Der Grund, warum Instanzvariablen mit einem Unterstrich beginnen, besteht darin, Programmierer daran zu erinnern, dass es eine schlechte Übung ist, sie jemals außerhalb ihrer Klasse aufzurufen. Sie können jedoch immer einen Accessor/Getter-Methode Ihrer Klasse hinzufügen:

def month(self): 
    return(self._month) 

diese Weise können Sie einfach

x.month() 

nennen kann den Monat mit x verbunden zu bekommen.

Verwandte Themen