2.23. Koristelijat¶
Koristelija on syntaksin pala, joka kietoo funktion (tai metodin) toiseen funktioon. Kääre voi lisätä käyttäytymistä ennen alkuperäistä kutsua ja sen jälkeen, korvata paluuarvon tai liittää metatietoja. Muoto on:
@wrapper
def f():
...
@wrapper-rivi vastaa lauseketta f = wrapper(f) – funktio f rakennetaan normaalisti, sitten luovutetaan funktiolle wrapper, ja tulos sidotaan uudelleen nimeen f.
Koristelija ottaa funktion sisään ja palauttaa uuden funktion.¶
2.23.1. Sisäänrakennetut metodikoristelijat¶
Muutama koristelija tulee Pythonin mukana ja niitä käytetään luokkarunkojen sisällä.
2.23.1.1. @property¶
Muuttaa metodin lasketuksi attribuutiksi. Kutsuja käyttää sitä kuin se olisi tavallinen attribuutti (ei sulkeita), mutta metodi suoritetaan jokaisella lukukerralla:
class Circle:
def __init__(self, radius):
self.radius = radius
@property
def area(self):
return 3.14159 * self.radius * self.radius
c = Circle(5)
print(c.area) # 78.53975 -- no parentheses
Käytä sitä, kun attribuutti, joka näyttää yksinkertaiselta, tarvitsee pienen laskennan taustalleen. Jos työ on kallista, suosi tavallista metodia – kutsujat eivät odota attribuuttilukujen olevan hitaita.
2.23.1.2. @classmethod¶
Määrittelee metodin, joka saa luokan ensimmäisenä argumenttinaan instanssin sijaan. Ensimmäinen parametri nimetään sopimuksen mukaan nimellä cls:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
@classmethod
def origin(cls):
return cls(0, 0)
p = Point.origin()
Luokkametodit ovat vakiotapa tarjota vaihtoehtoisia konstruktoreita – tehdasfunktioita, jotka palauttavat ei-oletustavalla rakennetun instanssin.
2.23.1.3. @staticmethod¶
Määrittelee metodin, joka ei saa instanssia eikä luokkaa – se on vain tavallinen funktio, joka elää luokan nimiavaruudessa järjestelysyistä:
class Temperature:
@staticmethod
def c_to_f(c):
return c * 9 / 5 + 32
Temperature.c_to_f(100) # 212.0
Käytä sitä säästeliäästi; jos funktiolla ei todella ole mitään tekemistä luokan tilan kanssa, tavallinen moduulitason funktio on yleensä siistimpi.
2.23.2. Mukautetun koristelijan kirjoittaminen¶
Koristelija on funktio, joka ottaa funktion ja palauttaa funktion. Vähimmäismuoto:
def log_calls(func):
def wrapper(*args, **kwargs):
print("calling", func.__name__)
return func(*args, **kwargs)
return wrapper
@log_calls
def add(a, b):
return a + b
add(2, 3)
Tuloste:
calling add
wrapper sulkeutuu func-funktion ympärille ja välittää kaiken sille. *args / **kwargs antaa sen toimia minkä tahansa funktion kanssa, ei vain kaksiargumenttisten. Tämä malli on perusta monimutkaisemmille koristelijoille (ajanotto, välimuistitus, uudelleenyritys epäonnistuessa), mutta ydin on aina sama: ota funktio sisään, palauta funktio ulos.