__ slots__ magic
Python is a language Dynamic language . Usually, dynamic languages allow us to bind new properties or methods to objects when the program is running. Of course, we can also unbind the bound properties and methods. However, if we need to restrict objects of custom types to bind only some properties, we can define them in the class__ slots__ Variable to qualify. It should be noted that__ slots__ The restriction of is only valid for the object of the current class and has no effect on the subclass.
First create a human named Celebrity
class Celebrity: # The restricted Celebrity object can only bind name, age and domain attributes __slots__ = ['name','age',"domain"] # Class Attribute species = 'human' # Initializer / Instance Attributes def __init__(self, name, age, domain): self.name = name self.age = age self.domain = domain
It can be found that three attributes are bound to Celebrity with slots. The main functions of slots are:
If you need to restrict objects of custom types to bind only some properties, you can define them in the class__ slots__ Variable to qualify. It should be noted that__ slots__ The restriction of is only valid for the object of the current class and has no effect on the subclass.
We remove the domian attribute of slots binding:
class Celebrity: # Class Attribute species = 'human' __slots__ = ['name', 'age'] # Initializer / Instance Attributes def __init__(self, name, age,domain): self.name = name self.age = age self.domain = domain female_leader = Celebrity("Miss Dong",65,"electrical appliance") # Access the instance attributes print("{} is {}.".format( female_leader.name, female_leader.age)) Out:AttributeError: 'Celebrity' object has no attribute 'domain'
You will find an error. Even if we have the domain attribute in the init method, because there is no domain attribute in slots, the instances created under the Celebrity class cannot have domain.
Next, let's briefly review how to call class variables:
female_leader = Celebrity("Miss Dong", 65,"electrical appliance") male_leader = Celebrity("Jack Ma", 55,"internet") # Access the instance attributes print("{} is {} and {} is {}.".format( female_leader.name, female_leader.age, male_leader.name, male_leader.age)) # Is male_leader a human? if male_leader.species == "human": print("{0} is a {1}!".format(male_leader.name, male_leader.species)) Out: Miss Dong is 65 and Jack Ma is 55. Jack Ma is a human!
Class inheritance and polymorphism
class Person(object): """people""" def __init__(self, name, age): self._name = name self._age = age @property def name(self): return self._name @property def age(self): return self._age @age.setter def age(self, age): self._age = age def play(self): print('%s Playing happily.' % self._name) def watch_av(self): if self._age >= 18: print('%s I'm watching a love action movie.' % self._name) else: print('%s Can only watch bear haunt.' % self._name) class Student(Person): """student""" def __init__(self, name, age, grade): super().__init__(name, age) self._grade = grade @property def grade(self): return self._grade @grade.setter def grade(self, grade): self._grade = grade def study(self, course): print('%s of%s I am learning%s.' % (self._grade, self._name, course)) class Teacher(Person): """teacher""" def __init__(self, name, age, title): super().__init__(name, age) self._title = title @property def title(self): return self._title @title.setter def title(self, title): self._title = title def teach(self, course): print('%s%s Talking%s.' % (self._name, self._title, course)) def main(): stu = Student('Da Chui Wang', 15, 'Junior three') stu.study('mathematics') stu.watch_av() t = Teacher('Luo Hao', 38, 'Brick house') t.teach('Python Programming') t.watch_av() if __name__ == '__main__': main()
After a subclass inherits the method of the parent class, it can give a new implementation version of the existing method of the parent class. This action is called method override. Through method rewriting, we can make the same behavior of the parent class have different implementation versions in the subclass. When we call the method rewritten by the subclass, different subclass objects will show different behaviors. This is polymorphism.
from abc import ABCMeta, abstractmethod class Pet(object, metaclass=ABCMeta): """Pets""" def __init__(self, nickname): self._nickname = nickname @abstractmethod def make_voice(self): """Make a sound""" pass class Dog(Pet): """dog""" def make_voice(self): print('%s: Woof, woof...' % self._nickname) class Cat(Pet): """cat""" def make_voice(self): print('%s: Meow...Meow...' % self._nickname) def main(): pets = [Dog('Wangcai'), Cat('Katie'), Dog('chinese rhubarb')] for pet in pets: pet.make_voice() if __name__ == '__main__': main()
In the above code, we treat the Pet class as an abstract class. The so-called abstract class is a class that cannot create objects. This kind exists specifically for other classes to inherit it. Python does not support abstract classes like Java or C# in terms of syntax, but we can achieve the effect of abstract classes through ABCMeta metaclass and abstractmethod wrapper of abc module. If there are abstract methods in a class, the class cannot be instantiated (create objects). In the above code, the two subclasses of Dog and Cat are respectively used to make in the Pet class_ The voice abstraction method is rewritten and different versions are implemented. When we call this method in the main function, this method shows polymorphic behavior (the same way does different things).