概述
面向过程: 分析解决问题的步骤, 用函数把步骤实现, 按顺序调用
函数式: 将某功能代码封装到函数中, 使用时直接调用函数
面向对象: 对函数进行分类和封装, 以对象为中心的编程
- class Cat: #class 创建类 Cat 类名称类开头习惯大写 类不需要返回值
- def __init__(self,name,type,sex) : # 根据类创建对象时自动执行
- self.name=name
- self.type=type
- self.sex=sex
- def call(self):
- print("一只叫 %s 的 %s 正在喵喵叫" %(self.name,self.type))
- def lick(self) :
- print("一只 %s 正在舔毛" %self.type)
- cat1=Cat('花小猫','布偶猫','女') #创建一个实例
- cat2=Cat('喵小胖','胖橘','女')
- print(cat1.__dict__) #实例的所有属性字典
- print(cat2.__dict__)
- cat1.call()# 调用属性
- cat2.lick()
- # 类的增删改查
- class School:
- country='china'
- def __init__(self,name,address):
- self.name=name
- self.address=address
- def Recruit_students(self) :
- print('%s 正在招生'%self.name)
- # 查看
- print(School.country)
- p1=School('bd','bj')
- print(p1.__dict__)
- print(p1.country)
- # 修改
- School.country='Japan'
- print(School.country)
- def text(self):
- print('text')
- School.Recruit_students=text
- p1.Recruit_students()
- # 增加
- School.type='full_time' #数据
- print(School.type)
- print(p1.type)
- def exam(self,place):
- print('%s 正在 %s 考试'%(self.name,place))
- School.exam=exam
- print(School.__dict__)
- p1.exam('classroom')
- # 删除
- del School.type
- print(School.__dict__)
- # 实例的增删改查
- class School:
- country='china'
- def __init__(self,name,address):
- self.name=name
- self.address=address
- def Recruit_students(self) :
- print('%s 正在招生'%self.name)
- p1=School('bd','bj')
- print(p1.__dict__)
- # 查看
- print(p1.name)
- print(p1.Recruit_students)
- # 增加
- p1.type='public'
- print(p1.__dict__)
- print(p1.type)
- # 修改
- p1.name='qh'
- print(p1.__dict__)
- print(p1.name)
- # 删除
- del p1.type
- print(p1.__dict__)
组合
- class School:
- def __init__(self,name,address):
- self.name=name
- self.address=address
- class Course:
- def __init__(self,name,price,period,school):
- self.name=name
- self.price=price
- self.period=period
- self.school=school
- s1=School('bd','bj')
- c1=Course('python','10000','6',s1)
- print(c1.school.name)
面向对象的三大特性: 继承, 多态, 封装
继承
python2: 新式类(广度继承), 经典类(深度优先)
python3: 新式类(广度优先)
继承顺序:
1, 子类先于父类
2, 多个父类根据它们在列表中的顺序检查
3, 对下一个类存在两个选择, 选择第一个父类
- class A:
- a='ff'
- class B(A):
- pass
- class C(A):
- pass
- class D(C):
- pass
- class E(D,C):
- pass
- print(E.a)
- class Ahsn:
- money=10
- def __init__(self,name):
- self.name=name
- def eat(self):
- print('%s 吃苹果' %self.name)
- class Bs:
- money=100
- def __init__(self,name):
- self.name=name
- def drink(self):
- print('%s 喝果汁'%self.name)
- class Cgh(Ahsn): #单继承
- pass
- class Djs(Ahsn,Bs): #多继承 (选择第一个父类)
- pass
- # 接口继承
- import abc
- class All(metaclass=abc.ABCMeta):
- @abc.abstractmethod
- def read(self):
- pass
- @abc.abstractmethod
- def write(self):
- pass
- class Disk(All):
- def read(self):
- print('disk read')
- def write(self):
- print('disk write')
- class Cdrom(All):
- def read(self):
- print('cdrom read')
- def write(self):
- print('cdrom write')
多态
不同的对象调用同一个方法
- class Animal:
- def __init__(self,name,height):
- self.name=name
- self.height=height
- def call(self):
- if self.height<15:
- print('%s 喵喵叫'%self.name)
- else:
- print('%s 汪汪叫' %self.name)
- class Dog(Animal):
- pass
- class Cat(Animal):
- pass
- d=Dog('泰日天',15)
- c=Cat('喵小胖',10)
- d.call()
- c.call()
封装
- # 普通封装
- class A:
- start='china'
- def __init__(self,name,age,hometown):
- self.name=name
- self.age=age
- self.hometown=hometown
- def introduce(self):
- print('我叫 %s 今年 %s 岁来自 %s' %(self.name,self.age,self.hometown))
- # 加一个_python 规定只能内部访问, 只是规定实际上外部可以访问到
- class B:
- _start='china'
- def __init__(self,name,age,hometown):
- self.name=name
- self.age=age
- self.hometown=hometown
- def introduce(self):
- print('我叫 %s 今年 %s 岁来自 %s' %(self.name,self.age,self.hometown))
- # 加两个_只能内部访问, 外部无法访问, 可调用接口访问
- class C:
- __start='china'
- def __init__(self,name,age,hometown):
- self.name=name
- self.age=age
- self.hometown=hometown
- def introduce(self):
- print('我叫 %s 今年 %s 岁来自 %s' %(self.name,self.age,self.hometown))
- def use(self):
- return C.__start
类内置方法 __getattr__,__setattr__,__delattr__
- class Sg:
- x=1
- def __init__(self,y):
- self.y=y
- def __getattr__(self, item):
- print('执行__getattr__')
- s=Sg('10')
- s.xh #属性不存在时执行__getattr__
- class Sg:
- x=1
- def __init__(self,y):
- self.y=y
- def __setattr__(self, key, value):
- print('执行__setattr__')
- self.__dict__[key]=value
- s=Sg(10)
- s.z=3
- print(s.__dict__)
- class Sg:
- x=1
- def __init__(self,y):
- self.y=y
- def __delattr__(self, item):
- self.__dict__.pop(item)
- print('执行__delattr__')
- s=Sg(10)
- del s.y
- print(s.y)
反射
- class Computer:
- type='notebook'
- def __init__(self,name,place):
- self.name=name
- self.place=place
- def play(self):
- print('%s 玩游戏很好用'%self.name)
- c=Computer('apple','Amercia')
- print(hasattr(c,'name')) #c 是否可以调用 name 可以返回 True, 不可以返回 False
- print(hasattr(c,'play'))
- func=getattr(c,'play')
- func()
- print(getattr(c,'name','没有这个属性')) #检查 c 中 name 对应的值
- print(getattr(c,'play','没有这个属性'))
- func=getattr(c,'play')
- func()
- setattr(c,'name','xiaomi') #修改
- setattr(c,'size','20') #增加
- setattr(c,'fg',lambda self:self.name+'h')
- print(c.fg(c))
- print(c.__dict__)
- delattr(c,'name') #删除
- print(c.__dict__)
动态导入模块
- import importlib
- d=importlib.import_module('m.n')
- d.a()
添加字符串
- class List(list):
- def append(self, object):
- if type(object) is str:
- # list.append(self,object)
- super().append(object)
- else:
- print('只能添加字符串')
- l=List('helloworld')
- l.append('fg')
- print(l)
授权
- import time
- class Open:
- def __init__(self,filename,mode='r',encoding='utf-8'):
- self.file=open(filename,mode,encoding=encoding)
- self.mode=mode
- self.encoding=encoding
- def write(self,line):
- t=time.strftime('%Y-%m-%d %X')
- self.file.write('%s%s'%(t,line))
- def __getattr__(self, item):
- return getattr(self.file,item)
- o=Open('a.txt','r+')
- o.write('11111\n')
- o.write('内存不足 \ n')
- o.seek(0)
- print(o.write)
- print(o.read())
- __str__,__repr__
- class F():
- def __init__(self,name):
- self.name=name
- def __str__(self): #print 返回值必须是字符串
- return 'g'
- def __repr__(self): #解释器中显示 返回值必须是字符串
- return 's'
- __format__ #自定制格式化方式
- class Date:
- def __init__(self,year,month,day):
- self.year=year
- self.month=month
- self.day=day
- def __format__(self, format_spec):
- dic = {'ymd': '{0.year}{0.month}{0.day}',
- 'y:m:d': '{0.year}:{0.month}:{0.day}',
- 'y-m-d': '{0.year}-{0.month}-{0.day}'}
- print('-->',format_spec)
- if format_spec not in dic:
- format_spec='ymd'
- x=dic[format_spec]
- return x.format(self)
- d=Date('2018','9','18')
- print(format(d,'ymd')
- __iter__,__next__ #实现迭代器
- class F:
- def __init__(self,n):
- self.n=n
- def __iter__(self):
- return self
- def __next__(self):
- if self.n==20:
- raise StopIteration('stop')
- self.n+=self.n
- return self.n
- f=F(1)
- print(next(f))
- print(f.__next__())
- for i in f:
- print(i)
- isintance,issubclass
- class A:
- pass
- class B(A):
- pass
- c=A()
- print(isinstance(c,A)) #实例 c 是否属于 A
- print(issubclass(B,A)) #B 是否是 A 的子类
- __getattribute__ #调用的属性是否存在都会调用__getattribute__
- class C:
- def __init__(self,x):
- self.x=x
- def __getattr__(self, item):
- print('getattr')
- def __getattribute__(self, item):
- print('getattribute')
- raise AttributeError('抛出异常')
- __getitem__,__setitem__,__delitem__ #以字典方式增删改查
- class D:
- def __init__(self,x):
- self.x=x
- def __getitem__(self, item):
- print('getitem')
- return self.__dict__[item]
- def __setitem__(self, key, value):
- self.__dict__[key]=value
- print('setitem')
- def __delitem__(self, key):
- print('delitem')
- self.__dict__.pop(key)
- d=D('h')
- print(d['x'])
- d['name']='ghy'
- del d['name']
- print(d.__dict__)
slots 属性 #实例无法调用__dict__, 节省内存
- class D:
- __slots__ = 'name'
- __doc__ #文档注释
- class D:
- '中国'
- __slots__ = 'name'
- d=D()
- print(d.__doc__)
中国
- __module__,__class__ #所在模块, 所在类
- class D:
- __slots__ = 'name'
- d=D()
- print(d.__module__)
- print(d.__class__)
- __del__ #析构方法当对象在内存被释放时, 立即触发__del__
- class A:
- def __init__(self,name):
- self.name=name
- def __del__(self):
- print('-->')
- a=A('ghy')
- del a
- print('==>')
- -->
- ==>
- __call__ #对象后面加 () 触发执行
- class A:
- pass
- def __call__(self, *args, **kwargs):
- print('df')
- a=A()
- a()
斐波那契数列
- class Q:
- def __init__(self):
- self.a=0
- self.b=1
- def __iter__(self):
- return self
- def __next__(self):
- if self.a>100:
- raise StopIteration('stop')
- self.a,self.b=self.b,self.a+self.b
- return self.a
- q=Q()
- print(next(q))
- print(next(q))
- print(next(q))
- print('--->')
- for i in q:
- print(i)
数据描述符
- class F:
- def __get__(self, instance, owner):
- print('get')
- def __delete__(self, instance):
- print('delete')
- def __set__(self, instance, value):
- print('set')
非数据描述符
- class F:
- def __get__(self, instance, owner):
- print('get')
- def __delete__(self, instance):
- print('delete')
调用顺序:
类属性>数据描述符
- class F:
- def __get__(self, instance, owner):
- print('get','-->')
- def __delete__(self, instance):
- print('delete')
- def __set__(self, instance, value):
- print('set')
- class A:
- x=F()
- def __init__(self,n):
- self.x=n
- A.x=1
- print(A.__dict__)
数据描述符>实例属性
- class F:
- def __get__(self, instance, owner):
- print('get')
- def __delete__(self, instance):
- print('delete')
- def __set__(self, instance, value):
- print('set')
- class A:
- x=F()
- def __init__(self,n):
- self.x=n
- a=A('g')
- a.x=1
- set
- set
实例属性>非数据描述符
- class F:
- def __get__(self, instance, owner):
- print('get')
- class A:
- x=F()
- a=A()
- a.x=1
- print(a.__dict__)
- {'x': 1}
上下文管理协议
- class Open:
- def __init__(self,name):
- self.name=name
- def __enter__(self):
- print('执行 enter')
- return self
- def __exit__(self, exc_type, exc_val, exc_tb): #exc_type 异常类, exc_val 异常值, exc_tb 追踪信息若无异常均为 None
- print('执行 exit')
- print(exc_tb)
- with Open('a.txt') as f: #触发__enter__ 得到的返回值交给 f
- print(f)
- # print(g) #如果有异常从异常处触发运行__exit__ 如果返回 True 可继续运行下面代码 else 直接显示异常
- print('==')
描述符
- class A:
- def __init__(self,x,y):
- self.x=x
- self.y=y
- def __get__(self, instance, owner):
- print('get')
- # print('instance 参数 %s' %instance)
- # print('owner 参数 %s' %owner)
- return instance.__dict__[self.x]
- def __set__(self, instance, value):
- print('set')
- # print('instance 参数 %s' % instance)
- # print('value 参数 %s' %value)
- if not isinstance(value,self.y):
- raise TypeError('%s 传入数值不是 %s' %(self.x,self.y))
- instance.__dict__[self.x]=value
- def __delete__(self, instance):
- print('delete')
- instance.__dict__.pop(self.x)
- def a(**kwargs):
- def b(obj):
- print('==>')
- for key,value in kwargs.items():
- setattr(obj,key,A(key,value))
- return obj
- print('-->')
- return b
- @a(name=str,age=int)
- class B:
- # name=A('name',str)
- # age=A('age',int)
- def __init__(self,name,age):
- self.name=name
- self.age=age
- b=B('ghy',18)
- print(b.__dict__)
- print(b.name)
- del b.name
- print(B.__dict__)
- View Code
装饰器
- def a(**kwargs):
- def b(obj):
- print('==>')
- for key,value in kwargs.items():
- setattr(obj,key,value)
- return obj
- print('-->')
- return b
- @a(x=1,y=1)
- class C:
- pass
- print(C.__dict__)
- View Code
自定制 property
- class Userproperty:
- def __init__(self,fun):
- self.fun=fun
- def __get__(self, instance, owner):
- print('get')
- # print(instance)
- # print(owner)
- if instance is None:
- return self
- res=self.fun(instance)
- setattr(instance,self.fun.__name__,res) #将第一个得到的字典放入__dict__中, 再次执行直接调取
- return res
- # def __set__(self, instance, value):
- # pass
- class B:
- def __init__(self,name,length,width):
- self.name=name
- self.length=length
- self.width=width
- @Userproperty
- def area(self):
- return self.length*self.width
- b=B('home',20,20)
- print(b.area)
- print(b.__dict__)
- print(b.area)
- print(b.area)
- View Code
- class A:
- def __init__(self):
- self.original_price=100.0
- self.discount=0.8
- @property
- def price(self):
- user_price=self.original_price*self.discount
- return user_price
- @price.setter
- def price(self,value):
- self.original_price=value
- @price.deleter
- def price(self):
- del self.original_price
- a=A()
- print(a.price)
- a.price=200
- print(a.price)
- del a.price
- View Code
元类 #产生类的类
- class A:
- pass
- a=A()
- print(type(a))
- print(type(A))
- def __init__(self,name):
- self.name=name
- def test(self) :
- pass
- B=type('B',(object,),{'x':1,'__init__':__init__,'test':test})
- print(B.__dict__)
建立类的两种方法
- class Mytype(type):
- def __init__(self,a,b,c):
- print('元类的构造函数执行')
- def __call__(self, *args, **kwargs):
- obj=object.__new__(self)
- self.__init__(obj,*args,**kwargs)
- return obj
- class A(metaclass=Mytype):
- def __init__(self,name):
- self.name=name
- a=A('ghy')
- print(a.__dict__)
自定义元类
来源: http://www.bubuko.com/infodetail-2775242.html