Python duck types and polymorphism
1. Duck type
When you see a bird that walks like a duck, swims like a duck, and calls like a duck, then this bird can be called a duck
class Cat(object):
def say(self):
print("i am a cat")
class Dog(object):
def say(self):
print("i am a dog")
class Duck(object):
def say(self):
print("i am a duck")
animal = Cat()
animal.say() # i am a cat
The above three classes all contain say
methods.
A first instance of animal
an object, then it may give the assignment to at run time Cat
, Dog
or Duck
so is uncertain.
In java
implementation, multi-state, this is generally done, define a parent class Animal
, which comprises a say
method, then the definition of an inherited Animal
class Cat
subclasses and Cat
override subclass say
method, so as to indicate Cat
a Animal
subclass.
Based on java
ideas, use python
language to realize the concept of polymorphism
class Animal:
def say(self):
print("i am a animal")
class Cat(Animal):
def say(self):
print("i am a cat")
Animal an = Cat()
#在java中声明变量时需要定义变量类型,python中不能这样写
an.say() #调用子类方法
The object instantiated in Python is a dynamic variable that can point to any type, which means that the method needs to be written in the class. The code is the same as below.
animal_list = [Cat,Dog,Duck]
for animal in animal_list:
animal().say()
# i am a cat
# i am a dog
# i am a duck
When all types of methods have implemented a common method name, they can call the same method cyclically and achieve polymorphism. Compared with the method java
that needs to inherit a parent class and rewrite the class, it is much simpler.
In other words, when all classes or objects implement a common method and the method name is the same, these classes can be classified as one type.
Second, let's look at another example
a = ["bobby1", "bobby2"]
b = ["bobby2", "bobby"]
name_tuple = ["bobby3", "bobby4"]
name_set = set()
name_set.add("bobby5")
name_set.add("bobby6")
a.extend(b)
print(a) # ["bobby1", "bobby2","bobby2", "bobby"]
Think of a question, extend
can the function only pass through a list?
The extend
function is defined like this in the source code
def extend(self, iterable: Iterable[_T]) -> None: ...
So extend
function only can be used as a parameter list, any object can be iterated are possible, and in the Python
middle tuple
, set
are iterable object.
So you can extend
pass the name_set
sum to the function name_tuple
.
a = ["bobby1", "bobby2"]
name_tuple = ["bobby3", "bobby4"]
name_set = set()
name_set.add("bobby5")
name_set.add("bobby6")
# a.extend(name_tuple)
# print(a) # ["bobby1", "bobby2","bobby3", "bobby4"]
a.extend(name_set)
print(a) # ["bobby1", "bobby2","bobby5", "bobby6"]
Three, pass an iterable class to the extend function
class Company(object):
def __init__(self, employee_list):
self.employee = employee_list
def __getitem__(self, item):
return self.employee[item]
def __len__(self):
return len(self.employee)
company = Company(["tom", "bob", "jane"])
a = ["bobby1", "bobby2"]
a.extend(company)
print(a) # ["bobby1", "bobby2","tom", "bob", "jane"]
extend
The function implicitly calls the iterator in the object, for example __iter__
, __getitem__
(it becomes an iterable object after the call).
Subsection
Magic functions in python make full use of the duck type. Many magic functions are written in objects, which can be recognized by the python interpreter itself. Many built-in python objects or built-in classes have very useful features, such as iterable Features, context manager, collection sequence related features, etc., the code itself is more flexible.