面向对象
面向对象格式
定义: class 类名: - 定义了一个类 def 函数名(self): - 在类中编写了一个"方法" pass 调用: x1 = 类名() - 创建了一个对象/实例化一个对象 x1.函数名() - 通过对象调用其中一个方法
self是什么
self参数是python帮助我们传递的,调用的是哪个实例,self就指向谁
构造方法
__new__(self)构造方法
__init__(self)初始化
class Foo(object): def __init__(self, a1, a2): # 初始化方法 """ 为空对象进行数据初始化 :param a1: :param a2: """ self.a1 = a1 self.a2 = a2 def __new__(cls, *args, **kwargs): # 构造方法 """ 创建一个空对象 :param args: :param kwargs: :return: """ return object.__new__(cls) # Python内部创建一个当前类的对象(初创时内部是空的.).
方法和函数的区别
写在类中的函数叫做方法,写在类外面的就是函数
对象.xxx ->>> 方法
类.xxx ->>>函数
xxx ->>>函数
打印查看:
方法 ->>> method
函数 ->>>function
代码检查
from types import MethodType, FunctionType def check(arg): """ 检查arg是方法还是函数? :param arg: :return: """ if isinstance(arg, MethodType): print('arg是一个方法') elif isinstance(arg, FunctionType): print('arg是一个函数')
面向对象的三大特性
封装
将相关功能封装到一个类中
class FuncOne: def func1(self): pass def func2(self): pass def func3(self): pass
将数据封装到一个对象中
class FuncTwo: def __init__(self, para1, para2, para3): self.para1 = para1 self.para2 = para2 self.para3 = para3
继承
为了实现代码的复用性
class FuncThree: def func1(self): pass class FuncFour(FuncThree): def func2(self): pass obj = FuncFour() obj.func1()
经典类和新式类:
python2:经典类和新式类(object)
python3:只有新式类
经典类的查找顺序:深度优先
新式类的查找顺序:C3算法(python2.3更新)
注意:super遵循的是__mro__执行顺序
多态
类的成员
累的变量
实例变量(字段)
实例变量是类中方法中的变量,调用时需要通过对象
class FuncChange: def __init__(self, para1, para2): self.para1 = para1 self.para2 = para2 obj = FuncChange(1,2) print(obj.para1)
类变量(静态字段)
写在类的里面,类里的方法外面,调用时通过类名
class ST: lst = [] def get_lst(self): self.lst.insert(0,33) return self.lst class TT(ST): lst = [11, 22] s1 = TT() s2 = TT() y1 = s1.get_lst() print(y1) y2 = s2.get_lst() print(y2) print(TT.lst)
class FuncChange: para_one = 123 def __init__(self, para1, para2): self.para1 = para1 self.para2 = para2 print(FuncChange.para_one)
类的方法
实例方法
类中普通的方法,包含self,通过对象调用
class FuncWay: def __init__(self, para1, para2): self.para1 = para1 self.para2 = para2 # 实例方法 def func1(self): print(self.para1) obj = FuncWay(1,2) obj.func1() # 实例方法调用
静态方法
@staticmethod,无需使用对象中封装的值,可以自己传参,且不需要self,通过类名执行
class FuncWay: def __init__(self, para1, para2): self.para1 = para1 self.para2 = para2 # 静态方法 @staticmethod def func2(para3): print(para3) FuncWay.func2(1) # 静态方法调用
类方法
@classmethod,包含cls,通过类名执行
class FuncWay: def __init__(self, para1, para2): self.para1 = para1 self.para2 = para2 # 类方法 @classmethod def func3(cls, para4): print(cls, para4) FuncWay.func3(1) # 类方法调用
类的属性
通过方法改造而来,@property
只有一个参数self,调用时无需加括号,因此适用于无需传参且有返回值时使用
class FuncProperty: @property def func(self): return 123 obj = FuncProperty() print(obj.func)
类的公有与私有
无论是类的变量,类的方法还是类的属性都有公有和私有,
公有就是在类的内外都可以调用,私有是只能在类的内部调用,私有的创建是在命名时在名字前加"__"
class Foo: a1 = 1 __a2 = 2 def __init__(self, num): self.num = num self.__salary = 1000 def data(self): print(self.num+self.a1) obj1 = Foo(666) obj2 = Foo(999) print(obj1.num) print(obj1.a1) obj1.num = 18 obj1.a1 = 99 print(obj1.num) print(obj1.a1) print(obj2.a1) print(obj2.num+Foo.a1) print(obj2.num+obj1.a1) 运行结果: 666 1 18 99 1 1000 1098
class Foo: a1 = 1 __a2 = 2 def __init__(self, num): self.num = num self.__salary = 100 def data(self): print(self.num+self.a1) obj = Foo(666) print(obj.num) print(obj.a1) print(obj.__salary) print(obj.__a2) print(Foo.a1) print(Foo.__a2) 运行结果: 666 1 Error Error 1 Error
class Base: @classmethod def f3(cls): print(cls) def f1(self): print("base.f1") self.f3() class Foo(Base): def f2(self): print("foo.f2") self.f1() obj = Foo() obj.f2() 运行结果: foo.f2 base.f1 <class '__main__.Foo'>
类的组合
调用其他类的成员
通过自己调self
class Base(object): def f1(self): print('调用了Base') class Foo(object): def f1(self): print('我是Foo') Base.f1(self) obj = Foo() obj.f1()
运行结果:
我是Foo
调用了Base
super,按照继承的顺序找下一个
class Foo(object): def f1(self): super().f1() print('我是Foo') class Bar(object): def f1(self): print('我是Bar') class Info(Foo, Bar): pass obj = Info() obj.f1() 运行结果: 我是Bar 我是Foo
特殊成员
当对象.属性没有时,触发__getattr__方法
类名()->自动执行__init__
class Foo(object):
def __init__(self, a1, a2):
self.a1 = a1
self.a2 = a2
def __init__(self, a1, a2): self.a1 = a1 self.a2 = a2 obj = Foo(1,2) print(obj.a1 + obj.a2) 运行结果: 3
对象()->自动执行__call__
class Foo(object):
def __init__(self, a1, a2):
self.a1 = a1
self.a2 = a2
def __call__(self, *args, **kwargs): print(11111, args, kwargs) return 123 #可以有返回值 obj = Foo(1,2) ret = obj(6, 4, 2, k1=456) print(ret) 运行结果: 11111 (6, 4, 2) {'k1': 456} 123
对象['xx']->自动执行__getitem__
class Foo(object):
def __init__(self, a1, a2):
self.a1 = a1
self.a2 = a2
def __getitem__(self, item): print(item) return 8 #有返回值 obj = Foo(1,2) ret = obj['wo'] print(ret) 运行结果: wo 8
对象['xx'] = xx ->自动执行__setitem__
class Foo(object):
def __init__(self, a1, a2):
self.a1 = a1
self.a2 = a2
def __setitem__(self, key, value): print(key, value, 111111111) #没有返回值 obj = Foo(1,2) obj['k'] = "setitem" 运行结果: k setitem 111111111
del 对象[xx] ->自动执行__delitem__
class Foo(object):
def __init__(self, a1, a2):
self.a1 = a1
self.a2 = a2
def __delitem__(self, key): print(key) obj = Foo(1,2) del obj['wo'] 运行结果: wo
对象+对象 ->自动执行__add__
class Foo(object):
def __init__(self, a1, a2):
self.a1 = a1
self.a2 = a2
def __add__(self, other): return self.a1 + other.a2 obj = Foo(1,2) obj1 = Foo(1,2) obj2 = Foo(88,99) ret = obj2 + obj1 print(ret) 运行结果: 90
with对象 ->自动执行__enter__/__exit__
class Foo(object): def __init__(self, a1, a2): self.a1 = a1 self.a2 = a2 def __enter__(self): print('1111') return 999 def __exit__(self, exc_type, exc_val, exc_tb): print('22222') obj = Foo(1,2) with obj as f: print(f) 运行结果: 1111 999 22222
class UserInfo(object): pass class Department(object): pass class StarkConfig(object): def __init__(self,num): self.num = num def changelist(self,request): print(self.num,request) def run(self): self.changelist(999) class RoleConfig(StarkConfig): def changelist(self,request): print(666,self.num) class AdminSite(object): def __init__(self): self._registry = {} def register(self,k,v): self._registry[k] = v(k) site = AdminSite() site.register(UserInfo,StarkConfig) site.register(Department,StarkConfig) print(len(site._registry)) # 3 for k,row in site._registry.items(): row.run()
__dict__
用字典反回形参和所传实参
class Foo(object): def __init__(self, name, age): self.name = name self.age = age def func(self): pass obj1 = Foo('张三', 19) obj2 = Foo('李四', 20) print(obj1.__dict__) print(obj2.__dict__) 运行结果: {'name': '张三', 'age': 19} {'name': '李四', 'age': 20}
__doc__
显示注释信息
class Foo(object): """ 返回此处的注释信息 """ def __init__(self): pass def func(self): pass def __str__(self): return "F1" obj = Foo() print(obj.__doc__) 运行结果: 返回此处的注释信息
__str__
打印对象时,显示的是__str__内的字符串,所以看到str不一定就是str,只有type检测出的str可信
class Foo(object): def __init__(self): pass def func(self): pass def __str__(self): return "F1" obj = Foo() print(obj, type(obj)) 运行结果: F1 <class '__main__.Foo'>
__iter__
将不可迭代对象变为可迭代对象
class Foo(object): def __init__(self, name, age): self.name = name self.age = age def func(self): pass def __iter__(self): return iter([11, 22, 33]) obj = Foo("张三", 18) for el in obj: print(el) 运行结果: 11 22 33
class Foo(object): def __init__(self, name, age): self.name = name self.age = age def func(self): pass def __iter__(self): yield 11 yield 22 yield 33 obj = Foo("张三", 18) for el in obj: print(el) 运行结果: 11 22 33
issubclass,type,isinstance
issubclass
检查第一个参数是否是第二个参数的子孙类
class Base(object): # 父 pass class Foo(Base): # 子 pass class Bar(Foo): # 孙 pass print(issubclass(Bar, Base)) print(issubclass(Bar, Foo)) 运行结果: True True
type
获取当前对象是由那个类创建的
class Foo(object): pass obj = Foo() print(obj, type(obj)) if type(obj) == Foo: print('obj是Foo类型') 运行结果: <__main__.Foo object at 0x00000000021EB9E8> <class '__main__.Foo'> obj是Foo类型
isinstance
检查第一个参数(对象)是否是第二个参数(类及父类)的实例
class Base(object): pass class Foo(Base): pass class Tuu: pass obj1 = Foo() print(isinstance(obj1, Foo)) print(isinstance(obj1, Base)) print(isinstance(obj1, Tuu)) 运行结果: True True False
反射
getattr
根据字符串的形式,去对象中找成员
if hasattr(handler,val): func_or_val = getattr(handler,val) # 根据字符串为参数,去模块中寻找与之同名的成员。 if isinstance(func_or_val,FunctionType): func_or_val() else: print(func_or_val)
from types import MethodType,FunctionType def func(i): if isinstance(i, MethodType) print("这是方法") elif isinstance(i, FunctionType) print("这是函数")
hasattr
根据字符串的形式,去判断对象中是否有成员
setattr
根据字符串的形式,动态的设置一个成员到内存中
delattr
根据字符串的形式,动态的删除一个成员(内存中)
class Foo(object): def __init__(self): object.__setattr__(self, 'info', {}) # 在对象中设置值的本质 def __setattr__(self, key, value): self.info[key] = value def __getattr__(self, item): print(item+"123") return self.info[item] obj = Foo() obj.name = 'sb' print(obj.name)