Co jsou magické metody v Pythonu a jak je používat

Jednou z méně známých, ale cenných funkcí Pythonu je schopnost implementovat magické metody na objekty. Pomocí magických metod můžeme psát čistší kód, který je intuitivní a snadno pochopitelný.

Pomocí magických metod můžeme vytvořit rozhraní pro interakci s objekty způsobem, který působí více Pythonic. Tento článek vám představí magické metody, probere osvědčené postupy pro jejich vytváření a prozkoumá běžné magické metody, se kterými se setkáte.

Co jsou magické metody?

Magické metody jsou metody Pythonu, které definují, jak se objekty Pythonu chovají, když jsou s nimi prováděny běžné operace. Tyto metody jsou zřetelně definovány s dvojitým podtržením před a za názvem metody.

V důsledku toho se jim běžně říká dunderovy metody, jako je dvojité podtržení. Běžnou dunderovou metodou, se kterou jste se již mohli setkat, je metoda __init__(), která se používá k definování konstruktorů tříd.

Metody dunder obvykle nejsou určeny k tomu, aby byly volány přímo ve vašem kódu; spíše je bude volat interpret během běhu programu.

Proč jsou magické metody užitečné?

Magické metody jsou užitečným konceptem v objektově orientovaném programování v Pythonu. Pomocí nich určíte chování vlastních datových typů, když se používají s běžnými vestavěnými operacemi. Mezi tyto operace patří:

🢢 Aritmetické operace

🢢 Srovnávací operace

🟢 Operace životního cyklu

🢢 Provoz zastoupení

Následující část pojednává o tom, jak implementovat magické metody, které definují, jak se aplikace chová při použití ve všech výše uvedených kategoriích.

Jak definovat magické metody

Jak již bylo zmíněno, magické metody specifikují chování objektů. Jako takové jsou definovány jako součást třídy objektu. Protože jsou součástí třídy objektů, berou jako první argument self, což je odkaz na samotný objekt.

  Jak nainstalovat a nastavit Plex Media Server na Linuxu

Mohou převzít další argumenty v závislosti na tom, jak je bude tlumočník vyvolávat. Jsou také zřetelně definovány dvěma podtržítky před a za jménem.

Implementace

Mnohé z toho, o čem jsme dosud diskutovali, se zdá být teoretické a abstraktní. V této části budeme implementovat jednoduchou třídu Rectangle.

Tato třída bude mít vlastnosti délky a šířky. Pomocí metody __init__ můžete určit tyto vlastnosti při vytváření instance. Kromě toho budete moci porovnat různé obdélníky, abyste zjistili, zda je stejný, menší nebo větší než jiný pomocí operátorů ==, < a >. A konečně, obdélník by měl být schopen poskytovat smysluplnou řetězcovou reprezentaci.

Nastavení kódovacího prostředí

Abyste mohli pokračovat v tomto návodu, budete potřebovat běhové prostředí Pythonu. Můžete použít místní, nebo můžete použít online kompilátor etechblog.cz Pythonu.

Vytvoření třídy Obdélník

Nejprve začněme definicí třídy Rectangle.

class Rectangle:
    pass

Vytvoření metody konstruktoru

Dále vytvoříme naši první magickou metodu, metodu konstruktoru třídy. Tato metoda vezme výšku a šířku a uloží je jako atributy na instanci třídy.

class Rectangle:
    def __init__(self, height, width):
        self.height = height
        self.width = width

Vytvoření magické metody pro reprezentaci řetězce

Dále chceme vytvořit metodu, která umožní naší třídě generovat lidsky čitelný řetězec reprezentující objekt. Tato metoda bude volána vždy, když zavoláme funkci str() předávající v instanci třídy Rectangle jako argument. Tato metoda bude také volána, když voláte funkce, které očekávají řetězec argument, jako je například funkce print.

class Rectangle:
    def __init__(self, height, width):
        self.height = height
        self.width = width

    def __str__(self):
        return f'Rectangle({self.height}, {self.width})'

Metoda __str__() by měla vrátit řetězec, který chcete reprezentovat objekt. V tomto případě vracíme řetězec ve formátu Rectangle(, <šířka>), kde výška a šířka jsou uložené rozměry obdélníku.

Vytváření magických metod pro srovnávací operace

Dále chceme vytvořit operátory porovnání pro operace rovné, menší než a větší než. Tomu se říká přetížení operátora. K jejich vytvoření používáme magické metody __eq__, __lt__ a __gt__. Tyto metody vrátí booleovskou hodnotu po porovnání oblastí obdélníků.

class Rectangle:
    def __init__(self, height, width):
        self.height = height
        self.width = width

    def __str__(self):
        return f'Rectangle({self.height}, {self.width})'

    def __eq__(self, other):
        """ Checking for equality """
        return self.height * self.width == other.height * other.width

    def __lt__(self, other):
        """ Checking if the rectangle is less than the other one """
        return self.height * self.width < other.height * other.width

    def __gt__(self, other):
        """ Checking if the rectage is greater than the other one """
        return self.height * self.width > other.height * other.width

Jak vidíte, tyto metody mají dva parametry. První je aktuální obdélník a druhá je další hodnota, se kterou se porovnává. Tato hodnota může být jiná instance obdélníku nebo jakákoli jiná hodnota. Logika toho, jak srovnání a podmínky, za kterých se srovnání vrátí jako pravdivé, jsou zcela na vás.

  Jak zapnout prostorový zvuk pro AirPods na iPhonu nebo iPadu

Běžné magické metody

V této další části probereme běžné magické metody, se kterými se setkáte a budete je používat.

#1. Aritmetické operace

Aritmetické magické metody jsou volány, když je instance vaší třídy umístěna na levou stranu aritmetického znaménka. Metoda bude volána se dvěma argumenty, z nichž první je odkaz na instanci. Druhá hodnota je objekt napravo od znaku. Metody a znaky jsou následující:

NameMethodSignDescriptionAddition__add__+Implementuje přidání. Subtraction__sub__–Implementuje odečítání.Multiplication__mul__*Implementuje multiplikaciDivision__div__/Implementuje dělení.Podlahové dělení__floordiv__//Implementuje dělení podlahy.

#2. Srovnávací operace

Stejně jako aritmetické magické metody jsou tyto metody volány, když je instance třídy, pro kterou jsou definovány, umístěna nalevo od operátoru porovnání. Také, stejně jako aritmetické magické metody, jsou volány se dvěma parametry; první je odkaz na instanci objektu. Druhý je odkaz na hodnotu na pravé straně znaménka.

NameMethodSignDescriptionLess than__lt__Implementuje větší než srovnáníEqual to__eq__==Implementuje hodnotu rovné s porovnáníLess než nebo rovno __le__>=Implementuje hodnotu menší než nebo rovnou porovnáníVětší než_ nebo rovno<=_ge srovnání

  Jak nainstalovat Gnome 40 na Debian 11

#3. Operace životního cyklu

Tyto metody budou volány v reakci na různé metody životního cyklu objektu, jako je vytvoření instance nebo odstranění. Konstruktor __init__ spadá do této kategorie. Běžné metody v této kategorii jsou uvedeny v tabulce níže:

NameMethodDescriptionConstructor__init__Tato metoda je volána vždy, když je odstraněn objekt třídy, pro kterou je definována. Lze ji použít k provádění akcí čištění, jako je zavření všech souborů, které otevřela.Deletion__del__Tato metoda je volána vždy, když je odstraněn objekt třídy, pro kterou je definována. Lze ji použít k provádění akcí čištění, jako je zavření všech souborů, které otevřela. New__new__Metoda __new__ je volána jako první, když je vytvořena instance objektu zadané třídy. Tato metoda je volána před konstruktorem a přebírá třídu i všechny další argumenty. Vrátí instanci třídy. Z velké části to není příliš užitečné, ale je zde podrobně popsáno.

#4. Zastupování

NameMethodDescriptionStr__str__Vrátí lidsky čitelnou řetězcovou reprezentaci objektu. Tato metoda se volá, když zavoláte funkci str() a předáte instanci třídy jako argument. Je také volána, když předáte instanci funkcím print() a format(). Jeho účelem je poskytnout řetězec, který je srozumitelný pro koncového uživatele aplikace. Repr__repr__Vrátí řetězcovou reprezentaci objektu, který používá vývojář. V ideálním případě by vrácený řetězec měl být bohatý na informace, takže můžete vytvořit identickou instanci objektu pouze z řetězce.

Nejlepší postupy pro vytváření magických metod

Magické metody jsou neuvěřitelné a zjednoduší váš kód. Při jejich používání je však důležité mít na paměti následující věci.

  • Používejte je střídmě – Implementace příliš mnoha magických metod ve vašich třídách ztěžuje pochopení vašeho kódu. Omezte se na implementaci pouze těch nezbytných.
  • Ujistěte se, že rozumíte důsledkům výkonu metod, jako jsou __setatrr__ a __getattr__, než je použijete.
  • Zdokumentujte chování vašich magických metod, aby ostatní vývojáři přesně věděli, co dělají. To jim usnadňuje jejich použití a ladění v případě potřeby.

Závěrečná slova

V tomto článku jsem představil magické metody jako způsob vytváření tříd, které lze použít s vestavěnými operacemi. Také jsem diskutoval o tom, jak jsou definovány, a prošel jsem příkladem třídy, kterou magické metody implementovaly. Dále jsem zmínil různé metody, které pravděpodobně budete používat a budete potřebovat, než se podělím o několik osvědčených postupů, které je třeba mít na paměti.

Dále se možná budete chtít naučit implementovat třídu Counter v Pythonu.