Einführung
In diesem Abschnitt werden einige integrierte Dekoratoren behandelt, die in Verbindung mit Methodendefinitionen verwendet werden.
This tutorial is from open-source community. Access the source code
💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken
In diesem Abschnitt werden einige integrierte Dekoratoren behandelt, die in Verbindung mit Methodendefinitionen verwendet werden.
Es gibt vordefinierte Dekoratoren, die verwendet werden, um spezielle Arten von Methoden in Klassendefinitionen anzugeben.
class Foo:
def bar(self,a):
...
@staticmethod
def spam(a):
...
@classmethod
def grok(cls,a):
...
@property
def name(self):
...
Gehen wir nacheinander durch.
@staticmethod
wird verwendet, um sogenannte statische Klassenmethoden (aus C++/Java) zu definieren. Eine statische Methode ist eine Funktion, die Teil der Klasse ist, aber auf Instanzen nicht operiert.
class Foo(object):
@staticmethod
def bar(x):
print('x =', x)
>>> Foo.bar(2) ## x=2
>>>
Statische Methoden werden manchmal verwendet, um internen Unterstützungs-Code für eine Klasse zu implementieren. Beispielsweise Code, um die erstellten Instanzen zu verwalten (Speicherverwaltung, Systemressourcen, Persistenz, Sperren usw.). Sie werden auch von bestimmten Designmustern verwendet (hier nicht behandelt).
@classmethod
wird verwendet, um Klassenmethoden zu definieren. Eine Klassenmethode ist eine Methode, die das Klass -Objekt als erstes Argument statt der Instanz erhält.
class Foo:
def bar(self):
print(self)
@classmethod
def spam(cls):
print(cls)
>>> f = Foo()
>>> f.bar()
<__main__.Foo object at 0x971690> ## Die Instanz `f`
>>> Foo.spam()
<class '__main__.Foo'> ## Die Klasse `Foo`
>>>
Klassenmethoden werden am häufigsten als Werkzeug zur Definition alternativer Konstruktoren verwendet.
class Date:
def __init__(self,year,month,day):
self.year = year
self.month = month
self.day = day
@classmethod
def today(cls):
## Beachten Sie, wie die Klasse als Argument übergeben wird
tm = time.localtime()
## Und verwendet wird, um eine neue Instanz zu erstellen
return cls(tm.tm_year, tm.tm_mon, tm.tm_mday)
d = Date.today()
Klassenmethoden lösen einige knifflige Probleme mit Funktionen wie Vererbung.
class Date:
...
@classmethod
def today(cls):
## Holt die richtige Klasse (z.B. `NewDate`)
tm = time.localtime()
return cls(tm.tm_year, tm.tm_mon, tm.tm_mday)
class NewDate(Date):
...
d = NewDate.today()
In Ihren Dateien report.py
und portfolio.py
ist die Erstellung eines Portfolio
-Objekts etwas verwirrt. Beispielsweise hat das report.py
-Programm Code wie diesen:
def read_portfolio(filename, **opts):
'''
Liest eine Datei mit einem Aktienportfolio in eine Liste von Wörterbüchern mit den Schlüsseln
name, shares und price ein.
'''
with open(filename) as lines:
portdicts = fileparse.parse_csv(lines,
select=['name','shares','price'],
types=[str,int,float],
**opts)
portfolio = [ Stock(**d) for d in portdicts ]
return Portfolio(portfolio)
und die portfolio.py
-Datei definiert Portfolio()
mit einem eigenartigen Initialisierer wie diesem:
class Portfolio:
def __init__(self, holdings):
self._holdings = holdings
...
Ehrlich gesagt ist die Verantwortungsabfolge ein bisschen verwirrend, weil der Code verteilt ist. Wenn eine Portfolio
-Klasse eine Liste von Stock
-Instanzen enthalten soll, sollten Sie vielleicht die Klasse etwas klarer gestalten. So:
## portfolio.py
import stock
class Portfolio:
def __init__(self):
self._holdings = []
def append(self, holding):
if not isinstance(holding, stock.Stock):
raise TypeError('Expected a Stock instance')
self._holdings.append(holding)
...
Wenn Sie ein Portfolio aus einer CSV -Datei lesen möchten, sollten Sie vielleicht eine Klassenmethode dafür erstellen:
## portfolio.py
import fileparse
import stock
class Portfolio:
def __init__(self):
self._holdings = []
def append(self, holding):
if not isinstance(holding, stock.Stock):
raise TypeError('Expected a Stock instance')
self._holdings.append(holding)
@classmethod
def from_csv(cls, lines, **opts):
self = cls()
portdicts = fileparse.parse_csv(lines,
select=['name','shares','price'],
types=[str,int,float],
**opts)
for d in portdicts:
self.append(stock.Stock(**d))
return self
Um diese neue Portfolio -Klasse zu verwenden, können Sie jetzt Code wie diesen schreiben:
>>> from portfolio import Portfolio
>>> with open('portfolio.csv') as lines:
... port = Portfolio.from_csv(lines)
...
>>>
Machen Sie diese Änderungen an der Portfolio
-Klasse und ändern Sie den report.py
-Code, um die Klassenmethode zu verwenden.
Herzlichen Glückwunsch! Sie haben das Lab zu Dekorierten Methoden abgeschlossen. Sie können in LabEx weitere Labs ausprobieren, um Ihre Fähigkeiten zu verbessern.