- 组合是使用其他类实例作为自己的一个属性 (has-a关系)
- 继承是子类继承父类的属性和方法 (is a 关系)
- 优先使用组合保存代码简单
代码简单说明继承和多态:
class Animal:
def run(self):
print("animal is running")
class Dog(Animal):
def run(self):
print("Dog is running")
class Cat(Animal):
def run(self):
print("cat is running")
def run(animal):
animal.run()
run(Dog())
run(Cat())
#output
Dog is running
cat is running
类变量与实例变量
- 类变量由所有实例共享
- 实例变量由实例单独享有
- 当我们需要在一个类的不同实例共享变量的时候使用类变量
- 都可以通过class.method()方式使用
- classmethod第一个参数是cls,可以引用类变量
- staticmethod使用起来和普通函数一样,只不过放在类中组织
- classmethod是为了使用类变量,staticmethod是代码组织的需要
- __new__是一个classmethod,__init__是一个instancemethod
- __new__方法返回一个创建的实例,而__init__什么都不返回。
- 只有__new__返回一个class的实例后面的__init__才能被调用
- 当创建一个新实例时调用__new__,初始化一个实例的时候用__init__。
举例:
class Person:
def __new__(cls, *args, **kwargs):
print("in __new__")
instance = super().__new__(cls)
return instance
def __init__(self, name, age):
print("in __init__")
self.name = name
self.age = age
p = Person('peter', 23)
print(p)
# output:
in __new__
in __init__
<__main__.Person object at 0x119beeeb0>
# 将return instance注销掉的话,output:
in __new__
None
元类(meta class)
创建类的类
- 元类允许我们控制类的生成,比如修改类的属性等
- 使用type定义元类
- 最常见的使用场景是ORM框架
- python一切兼对象,函数也可以当做参数传递
- 装饰器是接收函数作为参数,添加功能返回一个新函数的函数
- python中通过@使用装饰器
import time
def log_time(func):
def _log(*args, **kwargs):
begin = time.time()
res = func(*args, **kwargs)
print("use time: {}".format(time.time() - begin))
return res
return _log
@log_time
def mySleep(t):
time.sleep(t)
mySleep(1)
装饰器顾名思义,在原本的mySleep函数外套上_log函数,成为一个带有_log装饰功能的新函数。原本函数的参数依旧通过_log函数的形参传入。
装饰器也可以带参数:
import time
def log_time_with_param(use_int):
def decorator(func):
def _log(*args, **kwargs):
beg = time.time()
res = func(*args, **kwargs)
if use_int: print(int(time.time() - beg))
else: print(time.time() - beg)
return _log
return decorator
@log_time_with_param(False)
def my_sleep():
time.sleep(1)
my_sleep()
用类做装饰器:
import time
class LogTime:
def __call__(self, func):
def _log(*args, **kwargs):
beg = time.time()
res = func(*args, **kwargs)
print(time.time() - beg)
return res
return _log
@LogTime()
def my_sleep():
time.sleep(1)
return "hello"
print(my_sleep())
类装饰器加参数:
import time
class LogTime:
def __init__(self, use_int = False):
self.use_int = use_int
def __call__(self, func):
def _log(*args, **kwargs):
beg = time.time()
res = func(*args, **kwargs)
if self.use_int: print(int(time.time() - beg))
else: print(time.time() - beg)
return res
return _log
@LogTime(True)
def mysleep():
time.sleep(1)
mysleep()
装饰器的输出顺序:
@a
@b
@c
def f ():
pass
上述执行顺序:f = a(b(c(f)))
三、魔术方法- __new__用于生成实例
- __init__用于初始化实例
- __call__将不可调用的实例对象变为可调用的实例对象
先需要明白什么是可调用对象,平时自定义的函数、内置函数和类都属于可调用对象,但凡是可以把一对括号()应用到某个对象身上都可称之为可调用对象,判断对象是否为可调用对象可以用函数 callable。
举例:
class A:
def __init__(self):
print("__init__ ")
super(A, self).__init__()
def __new__(cls):
print("__new__ ")
return super(A, cls).__new__(cls)
def __call__(self, *args, **kwargs): # 可以定义任意参数
print('__call__ ')
print(args[0])
a = A()
a(12) # 调用a
print(callable(a))
# output:
__new__
__init__
__call__
12
True
- __del__析构函数,当删除一个对象时,则会执行此方法,对象在内存中销毁时,自动会调用此方法。
import time
class People:
def __init__(self, name, age):
self.name = name
self.age = age
def __del__(self): # 在对象被删除的条件下,自动执行
print('__del__')
obj = People("xu", 26)
# output:
__del__



