@TOC面向对象高级
详细叙述python面向对象高级的知识点
通过这一篇了解如下知识
1.继承和多态
2.魔方方法
3.静态方法和类方法
4.装饰器
一:继承和多态
继承:一个类从另外一个类把属性和方法直接继承过来,减少代码重写.
多态:子类在继承了父类的方法后,可以对父类已有的方法给出新的实现版本,这个动作称之为方法重写(override)。通过方法重写我们可以让父类的同一个行为在子类中拥有不同的实现版本,当我们调用这个经过子类重写的方法时,不同的子类对象会表现出不同的行为,这个就是多态(poly-morphism)。
import
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
@name.setter
def name(self,name)
self._name = name
@age.setter
def age(self,age)
self._age = age
def paly(self):
print '正在玩斗地主'
class student(person):
def __init__(self,name,age,grade):
super().__init__(name,age)
self._grade = grade
@property
def name(self):
return self._name
@property
def age(self):
return self._age
@name.setter
def name(self,name)
self._name = name
@age.setter
def age(self,age)
self._age = age
def study(self):
print '正在学习数学'
if __name__ == '__main__':
stu = student('华仔',18,'大二')
stu.play()
stu.study()
per = person('某人',36)
per.play()
上面的代码创建了两个类,一个person(父类),一个student(子类),student继承了父类的属性(name,age)和方法(play)
from abc import ABCMeta,abstractmethod
class Animal(object ,metaclass=ABCMeta):
def __init__(self,name):
self._name = name
def makeVoice(self):
pass
print '发出动物的声音'
class Dog(Animal):
def __init__(self,name):
super().__init__(name)
def makeVoice(self):
print '汪汪'
class Cat(Animal):
def __init__(self,name):
super().__init__(name)
def makeVoice(self):
print '喵喵'
if __name__ == '__main__':
dog = Dog('阿黄')
dog.makeVoice()
cat = Cat('阿良')
cat.makeVoice()
上述代码Dog和Cat继承Animal类,不同的类makeVoice了不同的版本,这就是多态。可以通过abc模块的ABCMeta元类和abstractmethod包装器来达到抽象类的效果
二:魔方方法
python自带的方法,天生的。方法两侧是双下划线。可以重写有不同行为。不需要调用,自动运行。
模仿方法 | 含义 |
---|---|
基本方法 | |
new(cls[, …]) | 1. new 是在一个对象实例化的时候所调用的第一个方法2. 它的第一个参数是这个类,其他的参数是用来直接传递给 init 方法3. new 决定是否要使用该__init__ 方法,因为 new 可以调用其他类的构造方法或者直接返回别的实例对象来作为类的实例,如果 new 没有返回实例对象,则 init 不会被调用4. new 主要是用于继承一个不可变的类型比如一个 tuple 或者 string |
init(self[, …]) | 构造器,当一个实例被创建的时候调用的初始化方法 |
del(self) | 析构器,当一个实例被销毁的时候调用的方法 |
call(self[, args…]) | 允许一个类的实例像函数一样被调用:x(a, b) 调用 x.call(a, b) |
repr(self) | 定义当被 repr() 调用时的行为 |
len(self) | 定义当被 len() 调用时的行为 |
repr(self) | 定义当被 repr() 调用时的行为 |
str(self) | 定义当被 str() 调用时的行为 |
bytes(self) | 定义当被 bytes() 调用时的行为 |
hash(self) | 定义当被 hash() 调用时的行为 |
bool(self) | 定义当被 bool() 调用时的行为,应该返回 True 或 False |
format(self, format_spec) | 定义当被 format() 调用时的行为 |
有关属性 | |
getattr(self, name) | 定义当用户试图获取一个不存在的属性时的行为 |
getattr(self, name) | 定义当用户试图获取一个不存在的属性时的行为 |
getattribute(self, name) | 定义当该类的属性被访问时的行为 |
setattr(self, name, value) | 定义当一个属性被设置时的行为 |
delattr(self, name) | 定义当一个属性被删除时的行为 |
dir(self) | 定义当 dir() 被调用时的行为 |
get(self, instance, owner) | 定义当描述符的值被取得时的行为 |
set(self, instance, value) | 定义当描述符的值被改变时的行为 |
delete(self, instance) | 定义当描述符的值被删除时的行为 |
比较操作符 | |
lt(self, other) | 定义小于号的行为:x < y 调用 x.lt(y) |
le(self, other) | 定义小于等于号的行为:x <= y 调用 x.le(y) |
eq(self, other) | 定义等于号的行为:x == y 调用 x.eq(y) |
ne(self, other) | 定义不等号的行为:x != y 调用 x.ne(y) |
gt(self, other) | 定义大于号的行为:x > y 调用 x.gt(y) |
ge(self, other) | 定义大于等于号的行为:x >= y 调用 x.ge(y) |
算数运算符 | |
add(self, other) | 定义加法的行为:+ |
sub(self, other) | 定义减法的行为:- |
mul(self, other) | 定义乘法的行为:* |
truediv(self, other) | 定义真除法的行为:/ |
floordiv(self, other) | 定义整数除法的行为:// |
mod(self, other) | 定义取模算法的行为:% |
divmod(self, other) | 定义当被 divmod() 调用时的行为 |
pow(self, other[, modulo]) | 定义当被 power() 调用或 ** 运算时的行为 |
lshift(self, other) | 定义按位左移位的行为:<< |
rshift(self, other) | 定义按位右移位的行为:>> |
and(self, other) | 定义按位与操作的行为:& |
xor(self, other) | 定义按位异或操作的行为:^ |
or(self, other) | 定义按位或操作的行为: |
反运算 | |
增量赋值运算 | iadd(self, other) |
定义赋值加法的行为:+= | isub(self, other) |
定义赋值减法的行为:-= | imul(self, other) |
定义赋值乘法的行为:*= | itruediv(self, other) |
定义赋值真除法的行为:/= | ifloordiv(self, other) |
定义赋值整数除法的行为://= | imod(self, other) |
定义赋值取模算法的行为:%= | ipow(self, other[, modulo]) |
定义赋值幂运算的行为:**= | ilshift(self, other) |
定义赋值按位左移位的行为:<<= | irshift(self, other) |
定义赋值按位右移位的行为:>>= | iand(self, other) |
定义赋值按位与操作的行为:&= | ixor(self, other) |
定义赋值按位异或操作的行为:^= | ior(self, other) |
定义赋值按位或操作的行为: | = |
一元操作符 | |
pos(self) | 定义正号的行为:+x |
neg(self) | 定义负号的行为:-x |
abs(self) | 定义当被 abs() 调用时的行为 |
invert(self) | 定义按位求反的行为:~x |
类型转换 | |
complex(self) | 定义当被 complex() 调用时的行为(需要返回恰当的值) |
int(self) | 定义当被 int() 调用时的行为(需要返回恰当的值) |
float(self) | 定义当被 float() 调用时的行为(需要返回恰当的值) |
round(self[, n]) | 定义当被 round() 调用时的行为(需要返回恰当的值) |
index(self) | 1. 当对象是被应用在切片表达式中时,实现整形强制转换2. 如果你定义了一个可能在切片时用到的定制的数值型,你应该定义 __index__3. 如果 index 被定义,则 int 也需要被定义,且返回相同的值 |
上下文管理(with 语句) | |
enter(self) | 1. 定义当使用 with 语句时的初始化行为2. enter 的返回值被 with 语句的目标或者 as 后的名字绑定 |
exit(self, exc_type, exc_value, traceback) | 1. 定义当一个代码块被执行或者终止后上下文管理器应该做什么2. 一般被用来处理异常,清除工作或者做一些代码块执行完毕之后的日常工作 |
容器类型 | |
len(self) | 定义当被 len() 调用时的行为(返回容器中元素的个数) |
getitem(self, key) | 定义获取容器中指定元素的行为,相当于 self[key] |
setitem(self, key, value) | 定义设置容器中指定元素的行为,相当于 self[key] = value |
delitem(self, key) | 定义删除容器中指定元素的行为,相当于 del self[key] |
iter(self) | 定义当迭代容器中的元素的行为 |
reversed(self) | 定义当被 reversed() 调用时的行为 |
contains(self, item) | 定义当使用成员测试运算符(in 或 not in)时的行为 |
三:静态方法和类方法
静态方法:使用装饰器@staticmethod。参数随意,没有“self”和“cls”参数,但是方法体中不能使用类或实例的任何属性和方法
调用:实例对象和类对象都可以调用
类方法:使用装饰器@classmethod。第一个参数必须是当前类对象,该参数名一般约定为“cls”,通过它来传递类的属性和方法(不能传实例的属性和方法);
调用:实例对象和类对象都可以调用。
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(Triangle.perimeter(t))
print(t.area())
# print(Triangle.area(t))
else:
print('无法构成三角形.')
if __name__ == '__main__':
main()
静态方法不需要实例,是一个独立的函数,不需要类的属性和方法。
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):
ctime = localtime(time())
return cls(ctime.tm_hour, ctime.tm_min, ctime.tm_sec)
def run(self):
"""走字"""
self._second += 1
if self._second == 60:
self._second = 0
self._minute += 1
if self._minute == 60:
self._minute = 0
self._hour += 1
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()
类方法将类本身作为对象进行操作。
四:装饰器
装饰器:简单来说就是为已存在的函数或对象添加新的功能。
(1):简单的装饰器
import time
def record_time(func):
"""自定义装饰函数的装饰器"""
@wraps(func)
def wrapper(*args,**kwargs):
start = time()
result = func(*args,**kwargs)
print (f'{func.__name__}:{time()-start}秒')
return result
return wrapper
(2):带参数的装饰器
from functools import wraps
from random import randint
from time import time ,sleep
import pymsql
def record(output):
def decorate(func):
@wraps(func)
def wrapper(*args,**kwargs):
start = time()
ret_value = func(*args,**kwargs)
output(func.__name__,time()-start)
return ret_value
return wrapper
return decorate
def output_to_console(fname,duration):
print ('%s:%.3f秒'%(fname,duration))
def output_to_file(fname,duration):
with open('log.txt','a') as f:
f.write('%s:%.3f秒\n'%(fname,duration))
def output_to_db(fname,duration):
con = pymysql.connect(host='localhost', port=3306,data \
base='test',charset='utf8',user='root',password='123456',autocommit=True)
try:
withcom.cursor() as cursor:
cursor.execute('insert into tb_record values (default, %s, %s)',
fame, '%.3f' % duration))
finally:
con.close()
@record(output_to_console)
def random_delay(min,max):
sleep(randint(min,max))
def main():
for _ in range(3):
random_delay(3,5)
#for _ inrange(3):
# random_delay.__wrapped__(3,5)
if __name__ == '__main__':
main()
(3):自定义装饰器类
from functools import wraps
from time import time
class Record():
def __init__(self,output):
self.output = output
def __call__(self,func):
@wraps(func)
def wrapper(*args,**kwargs):
start = time()
result = func(*args,**kwargs)
self.output(func.__name__,time()-start)
return result
return wrapper
(4)单例类
from functools import wraps
from threading import Lock
def singleton(cls):
instances = {}
lock = Lock()
@wraps(cls)
def wrapper(*args,**kwargs):
if cls not in instances:
with lock:
if cls not in instances:
instances[cls] = cls(*args,**kwargs)
return instances[cls]
return wrapper