Los métodos mágicos en Python son una colección de métodos que se asocian automáticamente con cada definición de clase en el lenguaje. Si crea sus propias clases, puede anular uno o más métodos mágicos estándar para personalizar su comportamiento. Hay muchos métodos mágicos en Python, e incluimos una tabla de ellos al final de este tutorial. Por ahora, queremos echar un vistazo a algunos de los métodos mágicos más utilizados que pueden ser útiles en la programación diaria. Los métodos mágicos se pueden usar para personalizar cómo se representan sus objetos como cadenas, controlar cómo se accede a los atributos de un objeto durante la obtención y configuración, verificar la igualdad y hacer que un objeto sea invocable como una función.
Representación de cadenas
Los dos primeros métodos mágicos que vamos a aprender son los que usa Python para generar representaciones de cadenas de objetos. Uno se llama __str__ y el otro se llama __repr__ . La función __str__ se utiliza para generar una descripción de cadena fácil de usar del objeto y, por lo general, está destinada a mostrarse al usuario. La función __repr__ se usa más para el desarrollador del software. Genera una cadena que se puede usar con fines de depuración, por lo que se usa para mostrar mucha información detallada. Estas funciones se invocan en un objeto de diversas formas. Cuando llama a la función print () y pasa el objeto, o cuando usa __str__ o__repr__ funciones de conversión, estos métodos serán llamados.
__str__ y __repr__
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | class Book(): def __init__(self, title, author, price): super().__init__() self.title = title self.author = author self.price = price # The __str__ function is used to return a user-friendly string # representation of the object def __str__(self): return f'{self.title} by {self.author}, costs {self.price}' # The __str__ function is used to return a developer-friendly string # representation of the object def __repr__(self): return f'title={self.title},author={self.author},price={self.price}' book1 = Book('Python Crash Course', 'Eric Matthes', 23.99) book2 = Book('Serious Python', 'Julien Danjou', 25.43) # print each object print(book1) print(book2) # use str() and repr() print(str(book1)) print(repr(book2)) |
Curso intensivo de Python por Eric Matthes, cuesta 23,99
Serious Python de Julien Danjou, cuesta 25,43
Curso intensivo de Python por Eric Matthes, cuesta 23,99
title = Serious Python, autor = Julien Danjou, precio = 25.43
Igualdad y comparación
Al usar los métodos mágicos de igualdad y comparación, podemos dar a los objetos la capacidad de compararse entre sí. El método mágico llamado eq, se llama a su objeto cuando se compara con otro objeto. El siguiente código también implementa el método mágico mayor o igual que y el método menos mágico.
__eq__ __ge__ __lt__
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | class Book(): def __init__(self, title, author, price): super().__init__() self.title = title self.author = author self.price = price def __eq__(self, value): if not isinstance(value, Book): raise ValueError('Can\'t compare book to non-book type') return (self.title == value.title and self.author == value.author and self.price == value.price) def __ge__(self, value): if not isinstance(value, Book): raise ValueError('Can\'t compare book to non-book type') return self.price >= value.price def __lt__(self, value): if not isinstance(value, Book): raise ValueError('Can\'t compare book to non-book type') return self.price < value.price book1 = Book('Python Crash Course', 'Eric Matthes', 23.99) book2 = Book('Serious Python', 'Julien Danjou', 25.43) book3 = Book('Automate the Boring Stuff with Python', 'Al Sweigart ', 26.99) book4 = Book('Python for Kids', 'Jason Briggs', 19.79) # Check for equality print(book1 == book3) print(book1 == book2) print(book3 == book3) # Check for greater and lesser value print(book2 >= book1) print(book2 < book1) print(book3 >= book2) # Sorting books books = [book1, book3, book2, book4] books.sort() print([book.title for book in books]) |
Falso
Falso
Cierto
Cierto
Falso
Cierto
['Python para niños', 'Curso intensivo de Python', 'Python serio', 'Automatiza las cosas aburridas con Python']
Acceso a atributos
Los métodos mágicos de Python también le brindan un control completo sobre cómo se accede a los atributos de un objeto. Una clase puede definir métodos que intercepten el proceso cada vez que se establece o recupera un atributo. Los métodos que veremos en la sección son los siguientes.
- __getattribute__ Se llama cuando se recupera un atributo. Tenga en cuenta que no puede acceder directamente al nombre del atributo, de lo contrario se crea un bucle recursivo
- Se llama a __setattr__ cuando se establece un valor de atributo. No establezca el atributo directamente aquí, de lo contrario, un bucle recursivo provocará un bloqueo
- Se llama a __getattr__ cuando falla la búsqueda de __getattribute__; puede generar atributos sobre la marcha con este método
__getattribute__ __setattr__ __getattr__
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | class Book(): def __init__(self, title, author, price): super().__init__() self.title = title self.author = author self.price = price self._discount = 0.1 def __str__(self): return f'{self.title} by {self.author}, costs {self.price}' def __getattribute__(self, name): if (name == 'price'): price = super().__getattribute__('price') discount = super().__getattribute__('_discount') return price - (price * discount) return super().__getattribute__(name) def __setattr__(self, name, value): if (name == 'price'): if type(value) is not float: raise ValueError('The "price" attribute must be a float') return super().__setattr__(name, value) def __getattr__(self, name): return name + ' is not here!' book1 = Book('Python Crash Course', 'Eric Matthes', 23.99) book2 = Book('Serious Python', 'Julien Danjou', 25.43) # Try setting and accessing the price book1.price = 37.95 print(book1) book2.price = float(40) # using an int will raise an exception print(book2) # If an attribute doesn't exist, __getattr__ will be called print(book1.randomprop) |
Curso intensivo de Python por Eric Matthes, cuesta 34.155
Serious Python de Julien Danjou, cuesta 36,0
¡randomprop no está aquí!
Hacer un objeto invocable
El método mágico __call__ tiene la interesante habilidad de hacer que un objeto sea invocable tal como llamarías a cualquier otra función en Python.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | class Book(): def __init__(self, title, author, price): super().__init__() self.title = title self.author = author self.price = price def __str__(self): return f'{self.title} by {self.author}, costs {self.price}' def __call__(self, title, author, price): self.title = title self.author = author self.price = price book1 = Book('Python Crash Course', 'Eric Matthes', 23.99) book2 = Book('Serious Python', 'Julien Danjou', 25.43) # call the object as if it were a function print(book1) book1('Learning Python', 'Mark Lutz', 44.94) print(book1) |
Curso intensivo de Python por Eric Matthes, cuesta 23,99
Aprender Python por Mark Lutz, cuesta 44,94
Referencia de métodos de Python Magic
Inicialización y construcción | Que hace |
---|
__nuevo __ ( cls, otro ) | Nos permite anular el paso nuevo de cualquier objeto mediante el método mágico __new__ |
__init __ ( yo, otro ) | Cuando se crea un objeto, se inicializa llamando al método __init__ en el objeto |
__del __ ( yo ) | __del__ es un método destructor que se llama tan pronto como se eliminan todas las referencias del objeto, es decir, cuando un objeto se recolecta como basura |
Operadores y funciones unarios | Que hace |
---|
__pos __ ( yo ) | Implementa comportamiento para unario positivo (por ejemplo, + algún_objeto ) |
__neg __ ( yo mismo ) | Implementa el comportamiento para cuando el unario - operador se llama en nuestro objetivo |
__abs __ ( yo ) | Es llamado por la función incorporada abs () . Elimina el signo negativo de un número (si es negativo) |
__invertir __ ( uno mismo ) | Utiliza el operador ~ . Es la operación de "inversión" o "complemento", en la que todos los bits de los datos de entrada se invierten |
__redondo __ ( uno mismo, n ) | Implementa el comportamiento de la función round () . Devuelve un número de punto flotante que es una versión redondeada del número especificado. |
__floor __ ( self ) | Implementa la incorporada en Math.floor () de función |
__ceil __ ( auto ) | ceil () devuelve el valor máximo de x, es decir, el número entero más pequeño no menor que x |
__trunc __ ( propio ) | Elimina los valores decimales que es lo math.trunc () hace |
Asignación aumentada | Que hace |
---|
__iadd __ ( yo, otro ) | suma con asignación: a + = b |
__isub __ ( yo, otro ) | resta con asignación: a - = b |
__imul __ ( yo, otro ) | multiplicación con asignación: a * = b |
__ifloordiv __ ( yo, otro ) | división entera con asignación: a // = b |
__idiv __ ( yo, otro ) | división con asignación: a / = b |
__itruediv __ ( yo, otro ) | verdadera división con asignación |
__imod __ ( yo, otro ) | módulo con asignación: a% = b |
__ipow __ ( yo, otro ) | exponentes con asignación: a ** = b |
__ilshift __ ( yo, otro ) | desplazamiento bit a la izquierda con asignación: a << = b |
__irshift __ ( uno mismo, otro ) | desplazamiento a la derecha bit a bit con asignación: a >> = b |
__iand __ ( yo, otro ) | AND bit a bit con asignación: a & = b |
__ior __ ( yo, otro ) | OR bit a bit con asignación: a | = b |
__ixor __ ( yo, otro ) | XOR bit a bit con asignación: a ^ = b |
Conversión de tipo | Que hace |
---|
__int __ ( yo ) | int () método para convertir un tipo en un int |
__float __ ( auto ) | método float () para convertir un tipo en flotante |
__complejo __ ( propio ) | método complex () para convertir un tipo en complejo |
__oct __ ( yo ) | método oct () para convertir un tipo a octal |
__hex __ ( propio ) | método hex () para convertir un tipo a hexadecimal |
__index __ ( propio ) | Implementa la conversión de tipo a un int cuando el objeto se usa en una expresión de sector |
__trunc __ ( propio ) | Recibir una llamada de matemáticas. método trunc () |
Métodos de magia de cuerdas | Que hace |
---|
__str __ ( yo ) | método str () para devolver una representación de cadena de un tipo |
__repr __ ( yo ) | método repr () para devolver una representación legible por máquina de un tipo |
__unicode __ ( propio ) | método unicode () para devolver una cadena Unicode de un tipo |
__format __ ( self, formattr ) | método string.format () para devolver un nuevo estilo de cadena |
__hash __ ( yo ) | método hash () para devolver un entero |
__nonzero __ ( yo ) | método bool () para devolver verdadero o falso |
__dir __ ( yo ) | método dir () para devolver una lista de atributos de una clase |
__tamaño de __ ( propio ) | Método sys.getsizeof () para devolver el tamaño de un objeto |
Métodos mágicos de atributos | Que hace |
---|
__getattr __ ( yo, nombre ) | se llama cuando el atributo de acceso de una clase que no existe |
__setattr __ ( yo, nombre, valor ) | llamado al asignar un valor al atributo de una clase |
__delattr __ ( yo, nombre ) | llamado al eliminar un atributo de una clase |
Métodos mágicos del operador | Que hace |
---|
__add __ ( yo, otro ) | agregar operación usando + operador |
__sub __ ( yo, otro ) | operación de resta usando - operador |
__mul __ ( yo, otro ) | operación de multiplicación usando el operador * |
__floordiv __ ( yo, otro ) | operación de división de piso usando // operador |
__div __ ( yo, otro ) | operación de división usando / operator |
__mod __ ( yo, otro ) | operación de módulo usando el operador % |
__pow __ ( yo, otro [, módulo] ) | calculando la potencia usando ** operador |
__lt __ ( yo, otro ) | comparación usando < operador |
__le __ ( yo, otro ) | comparación usando <= operador |
__eq __ ( yo, otro ) | comparación usando == operador |
__ne __ ( yo, otro ) | comparación usando ! = operador |
__ge __ ( yo, otro ) | comparación usando > = operador |
0 Comentarios