table of Contents
Preamble: the last chapter we learned about the basics of object-oriented, this chapter we will object-oriented knowledge for further exploration
1. @property decorator
The last chapter, when we're talking about access to the property, although we do not recommend the property to private, but if the property is directly exposed directly to the outside world is also problematic, for example, we can not check whether the value assigned to the property effective. We recommend that before the attribute names that begin with a single underscore, in this way to imply that property is protected, but the property is in the logic verification method where, we can not allow them to pass 实例.属性
the time assignment also to go that set of logic we check properties. If we want to do that, we will need to use @property
a decorator to wrap getter and setter methods
# -*- coding:utf-8 -*-
"""
@Property 装饰器
version:0.1
author:coke
"""
class Person(object):
def __init__(self,name,age):
self.__name = name
self.__age = age
#访问器
@property
def name(self):
return self.__name
#访问器 - getter方法
@property
def age(self):
return self.__age
@age.setter
def age(self,age):
if age < 0 or age > 150:
print("年龄参数不正确")
return
self.__age = age
def play(self):
if self.__age <= 16:
print("%s正在玩飞行棋."%self.__name)
else:
print("%s正在玩斗地主."%self.__name)
def main():
person = Person("Jack",12)
person.age = -1
person.play()
if __name__ == "__main__":
main()
Output
Summary:@property
widely used in the definition of class, allowing the caller to write a short code, while ensuring the necessary checks on the parameters, so that the program is running reduces the likelihood of errors
2. Magic Methods
Python is a dynamic language . Typically, dynamic languages allow new property or method we bind to the object in the running, of course, can unbind the properties and methods have been bound. But if we need to define custom type of object can only bind certain properties, it can be defined in the class __slots__
to define variables. Note that __slots__
the only object that is currently defined class of entry into force of the sub-class does not play any role.
# -*- coding:utf-8
"""
slots
version:0.1
author:coke
"""
class Person(object):
# 限定Person对象只能绑定_name,_age 和 _gender属性
__slots__ = ('_name', '_age', '_gender')
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):
if self._age <= 16:
print("%s正在玩飞行棋,年龄%d" % (self._name, self._age))
else:
print("%s正在玩斗地主,年龄%d" % (self._name, self._age))
def main():
person = Person("Jack",18)
person.play()
if __name__ == "__main__":
main()
Summary:__slots__
variables, you can limit the attributes of the class instance can be added.
3. The class and instance properties
In the previous example we come into contact is an instance attribute (object attribute), by definition, the class attribute is the class object owned property, it is common to instances of objects of all the object's class, there is only one copy in memory, for the public class attributes, the outer class object classes and instances can access the object
class attribute
class People(object):
address = "山东"
def __init__(self):
self.name = "xiaowang" #实例属性
self.age = 20
p = People()
p.age = 12
print(p.address) #正确
print(People.address) #正确
print(p.name) #正确
print(p.age) #正确
print(People.address)#正确
#print(People.age) #错误
#print(People.name) #错误
Summary: Examples of properties can not be 类对象.实例属性
acquired, either through the class attribute 类对象.类属性
acquisition, can also 实例对象.类属性
obtain
By way of example (object) to modify class attributes
class People(object):
country = 'china' #类属性
print(People.country) #china
p = People()
print(p.country) #china
p.country = "japan"
print(p.country) #japan
print(People.country) #china
del p.country
print(p.country) #china
Summary: class attribute even though you can 实例对象.类属性
, but can not be modified instance object classes and attributes to delete access if the instance of an object declaration of the same name, the property belongs to the property Instance Properties
4. The method of static methods and classes
Before, we define a method in the class is an object method, that these methods are sending a message to the object. In fact, we wrote in class method does not require all object methods, we can also create static methods and class methods as needed
Static method
"""
静态方法
version:0.1
author:coke
"""
from math import sqrt
class Triangle(object):
def __init__(self,a,b,c):
self._a = a
self._b = b
self._c = c
@staticmethod
def is_valid(a,b,c):
return a + b > c and b + c > a and a + c > b
def perimeter(self):
return self._a + self._b + self._c
def area(self):
half = self.perimeter() / 2
return sqrt(half * (half - self._a) * (half - self._b) * (half - self._c))
def main():
a,b,c = 3,4,5
if Triangle.is_valid(a,b,c):
t = Triangle(a,b,c)
print(t.perimeter())
print(t.area())
else:
print("无法构成三角形")
if __name__ == '__main__':
main()
Summary: By decorator @staticmethod
to modify the method, which we call static methods and static methods can be called directly through the class object
Class Methods
"""
类方法
version:0.1
author:coke
"""
from time import time, localtime, sleep
class Clock(object):
def __init__(self, hour=0, minute=0, second=0):
self._hour = hour
self._minute = minute
self._second = second
@classmethod
def now(cls):
ctimes = localtime(time())
return cls(ctimes.tm_hour, ctimes.tm_min, ctimes.tm_sec)
def run(self):
self._second += 1
if self._second == 60:
self._second = 0
self._minute += 1
if self._minute == 60:
self._hour += 1
self._minute = 0
if self._hour == 24:
self._hour = 0
def show(self):
return "%02d:%02d:%02d" % \
(self._hour,self._minute,self._second)
def main():
clock = Clock.now()
while True:
print(clock.show())
sleep(1)
clock.run()
if __name__ == "__main__":
main()
Summary: with the modified device @classmethod
to identify it as a class method, for a class method, the first parameter must be a class object, generally cls
as the first parameter, it is possible to access the object and the class object by way of example, and has been obtained since the parameter is equal to cls indirect access to such information, so we can create a class object class method by
5. Single and multiple inheritance
In the program, describes the inheritance belongs relationship between things, such as cats and dogs belong to the animal, the program can be described as cats and dogs inherited from animals; Similarly, Bali and Persian cats are inherited from the cat, and Shar Pei and Dalmatians inherit enough, as shown below:
Single inheritance refers only to inherit a parent class information, multiple inheritance was to inherit more than one parent class information . To know that most programming languages allow only single inheritance, because there will be problems caused by diamond inheritance. But in python but the accident to allow the emergence of multiple inheritance
single inheritance
# 继承object类父类信息
class Person(object):
"""人"""
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正在愉快的玩耍."% self._name)
def watch_tv(self):
if self._age >= 18:
print("%s 正在看刺激的电影"%self._name)
else:
print("%s 正在看熊出没"%self._name)
# (person) 继承person父类信息
class Student(Person):
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):
self._grade = grade
def study(self,course):
print("%s的%s正在学习%s."%(self._grade,self._name,course))
#继承 person父类信息
class Teacher(Person):
"""老师"""
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 teacher(self,course):
print("%s%s正在讲%s."%(self._name,self._title,course))
def main():
stu = Student("Jack",15,"初二")
stu.study("数学")
stu.watch_tv()
t = Teacher("Marry",38,"专家教授")
t.teacher("语文")
t.watch_tv()
if __name__ == "__main__":
main()
Output
Multiple Inheritance
#coding=utf-8
class base(object):
def test(self):
print('----base test----')
class A(base):
def test(self):
print('----A test----')
# 定义一个父类
class B(base):
def test(self):
print('----B test----')
# 定义一个子类,继承自A、B
class C(A,B):
pass
obj_C = C()
obj_C.test()
print(C.__mro__) #可以查看C类的对象搜索方法时的先后顺序
Output
Summary: When diamond inheritance problems, who to call, depending on the resolution order ( MRO )
6. Polymorphism
After the subclass inherits the parent class, you can give a new version of the realization of the existing parent class, this action is called method overrides (override). By rewriting method we can make the same behavior of the parent class has a different version in a subclass to achieve, when we call passes this subclass rewritten, different subclasses of objects exhibit different behavior, this is the polymorphism (poly-morphism).
"""
多态
version:0.1
author:coke
"""
from abc import ABCMeta,abstractmethod
class Pet(object,metaclass=ABCMeta):
"""
宠物
"""
def __init__(self, nickname):
self._nickname = nickname
@abstractmethod
def make_voice(self):
"""发出声音"""
pass
class Dog(Pet):
"""狗"""
def make_voice(self):
print('%s: 汪汪汪...' %self._nickname)
class Cat(Pet):
def make_voice(self):
print("%s:喵喵喵...." %self._nickname)
def main():
#利用多态性质进行不同的声音的输出
pets = [Dog('旺财'),Cat('凯迪'),Dog('索拉')]
for pet in pets:
pet.make_voice()
if __name__ == '__main__':
main()
Analysis: using the abc module implements an abstract class, abc.ABCMeta abstract base class is a class, implement @abstractmethod
the definition of abstract methods without having to realize the function, subclass inherits the abstract method abstract class abstract class must override. Abstract method like a template method
7. del Methods
After you create an object, python interpreter calls the default __init__()
method; when an object is deleted, python interpreter will be a default method calls, this method is __del__()
a method
import time
class Animal(object):
#初始化方法
#创建完对象后自动被调用
def __init__(self,name):
print("init方法被调用")
self.__name = name
#析构方法
#当对象被删除时,会自动被调用
def __del__(self):
print("del方法被调用")
print("%s对象马上被干掉了..."%self.__name)
dog = Animal("田园犬")
#删除对象
del dog
cat = Animal("波斯猫")
print("准备删除波斯猫了....")
del cat
Output