赞
踩
python中的函数式编程和面向对象编程
函数式编程:方法(函数)
面向对象编程:类
功能 : python中,面向对象编程能实现的,函数式编程也基本能都实现
面向对象编程适用:当多个函数有多个相同参数时,使用面向对象编程更为方便
class student: #声明一个学生类
def __init__(self,name,age): #构造方法(创建类的对象时自动执行)
self.name = name #普通字段
self.age = age
def stu_show(self):
print('%s - %s岁'%(self.name,self.age))
def ret(self): #普通方法
print('这是一个学生类')
def __del__(self): #析构方法:对象被销毁时,自动调用
print('析构方法')
stu = student('小明',17) #创建一个类的对象
stu.ret() #中间人(stu)调用类中方法
stu.stu_show()
声明的类默认继承object类
self : 可以理解为是指调用方法的对象,即上述的:stu
证明self:
class person:
def show(self,num):
print(self,num) #验证self地址
p1 = person()
print(p1)
p1.show(32)
#输出:
<__main__.person object at 0x0000022F07486700> #地址相同
<__main__.person object at 0x0000022F07486700> 32
class student:
def __init__(self,name,age):
self.name = name
self.age = age
def show(self):
print(self.name,self.age,self.hobby)
stu = student('小明',19)
stu.hobby = 'girl' #对象存数据
stu.show()
#输出:
小明 19 girl
class teacher:
def __init__(self,name,course):
self.name = name
self.course = course
teacher1 = teacher('王刚','高数') #这是利用__init__()方法进行封装
teacher1.hobby = '篮球' #这是封装
teacher2 = teacher('王李安','英语')
teacher2.hobby = '冲浪'
继承运用: 不修改原类,为其添加新功能
代码编写应当遵循:开发封闭原则(修改禁止,添加扩展允许)
class father: def f(self): print('这是父方法') def m(self): print('父方法2') class son(father): def f(self): #重写:父类含有的方法,在子类内再次编写 print('父方法重写') def function(self): super(son,self).f() #重写后,想要调用父类方法:super():超级(超集) father.f(self) #与super效果相同,但是推荐用super son1 = son() son1.f() #类内有的方法将优先调用类内 son1.m() #继承至父类的m()方法 son1.function() #输出: 父方法重写 父方法2 这是父方法 这是父方法
class father:
def show(self):
print('父1')
class father2:
def show(self):
print('父2')
class son(father2,father):
pass
son1 = son()
son1.show()
#输出:
父2
1.多继承中,父类没有继承爷爷类,子类继承多个父类时,调用父类中相同的方法,将默认从继承左端的第一个父类开始寻找。
图例:
2.多继承中,父类继承不同的爷爷类,爷爷类继承不同的祖父类,子类继承多个父类时,子对象调用继承方法,将默认从继承左端第一个父类开始寻找,接着找完该父类所有爷爷和祖父类,再开始找下一个父类,以此类推。
图例:
3.多继承中,父类继承不同的爷爷类,爷爷类继承同一个祖父类,子类继承多个父类时,子类对象调用继承方法,将默认从继承左端第一个父类开始寻找,找到该父类的爷爷类时截止,接着找下一个父类,同样找到爷爷类时截止,直到找到最后一个父类时,才找祖父类,即:根类放在最后查找
图例:
class father: def show(self): print('父1') def ret(self): self.show() #父类内调用show()方法,父类1和父类2都含有show方法,那么将调用哪个呢? class father2: def show(self): print('父2') class son(father2,father): pass son1 = son() son1.show() son1.ret() #输出: 父2 #时刻记住,self指的是调用方法的对象,而此时self指代son1,也就是son类,而son类中,先继承父类2,才继承父类1,所以将调用父类2中的show方法 父2
多态可以理解为定义多种数据类型,整型(int),字符型(string)等等。
在c,c++,java中,定义一个变量时,需要说明它的数据类型,而在python中,解释器将会根据运用自动判断其数据类型。
即:原生多态
class ret:
hobby = '网游' #静态字段,数据保存在类中,可以通过对象和类调用
def __init__(self,name):
self.name = name #普通字段,数据保存在对象中,只能通过对象调用
son1 = ret('小明')
son1.name = '小刚'
ret.hobby #son1.hobby
class test:
def ret1(self): #普通方法
print('没想到吧?')
@staticmethod #静态方法,由类直接调用
def ret2(): #静态方法中,self将不再必须,即可以删掉self后,不传入参数,也可以自主定义传入参数
print('这是静态方法')
t1 = test()
t1.ret1() #对象调用普通方法 无论哪种调用方法,都需先创建一个对象
test.ret1(t1) #类调用普通方法
test.ret2() #类直接调用静态方法,不用传入对象
class test: def ret1(self): print('没想到吧?') @property def ret2(self): #对应:t1.ret2 print('这是伪造成字段的方法') @ret2.setter def ret2(self,num): #对应:t1.ret2 = 5 print('这是方法2 num:%s'%num) @ret2.deleter def ret2(self): #对应:del t1.ret2 print('这是第三种调用方式') t1 = test() t1.ret2 t1.ret2 = 5 del t1.ret2 #为调用同一函数名的不同方法,提供了三种不同的调用方式,这里的del将不代表删除,而是用来表示一种方法的调用形式, #输出: 这是伪造成字段的方法 这是方法2 num:5 这是第三种调用方式
class seted: def f1(self): print('方法 1') def f2(self,num): print('方法 2 num:%s'%num) def f3(self): print('方法 3') ret1 = property(fget=f1,fset=f2,fdel=f3) #ret1 = property(f1,f2,f3) set1 = seted() set1.ret1 set1.ret1 = 4 del set1.ret1 #输出: 方法 1 方法 2 num:4 方法 3
class student: def __init__(self, name, age): self.name = name self.__age = age # 在变量名前加上 __(两个下划线),即使变量成为类中私有,类外将不能直接调用 def __function(self): #__<方法名> :私有方法 print("这是私有方法") def function_show(self): #类内可以调用私有方法 self.__function() def show(self): #类内可以调用私有变量 print('私有变量__age = %s' % self.__age) stu1 = student('小明', 17) print(stu1.name) #print(stu1.__age) #报错,找不到变量__age stu1.show() #对象通过类内的方法,调用私有变量 #stu1.__function() #报错,找不到方法__function() stu1.function_show() ##通过类内方法调用私有方法 #输出: 小明 私有变量__age = 17 这是私有方法
提要 :继承中,子类无法直接调用父类的私有变量和私有方法。
lass student:
def __init__(self):
pass
def __call__(self, *args, **kwargs):
print('这是call方法')
stu1 = student()
stu1() #在类对象后加上()括号,将自动调用类中的call方法
#输出:
这是call方法
class student:
def __init__(self):
pass
def __int__(self):
return 4
stu1 = student()
stu1 = int(stu1) #调用类中的__int__方法,并取得返回值
print(stu1)
#输出
4
class student:
def __init__(self,name,age):
self.name = name
self.age = age
def __str__(self):
return '%s %s'%(self.name,self.age)
stu1 = student('小明',18)
print(stu1) #相当于print(str(stu1)) 调用类中的__str__方法并返回
#输出:
小明 18
__dict__方法:将类或对象中的数据制作成字典,并返回
class student:
def __init__(self,name,age):
self.name = name
self.age = age
self.hobby = 'pcgame'
stu1 = student('小明',18)
f = stu1.__dict__ #将对象中的数据制作成字典
#student.__dict__ #将类中的数据制作成字典并返回
print(f)
#输出:
{'name': '小明', 'age': 18, 'hobby': 'pcgame'}
class student: def __init__(self): self.hobby = 'pcgame' def __getitem__(self, item): print('还是方法:item:%s'%item) return item+1000 def __setitem__(self, key, value): print(key,value) def __delitem__(self, key): print(key) stu1 = student() s = stu1[800] #在类的对象后加上一个[]中括号,填上参数,将默认执行类中的__getitem__方法,并传入参数,有返回值 print(s) stu1[1000] = '这就是第二种方法' #默认执行类中__setitem__方法,没有返回值 del stu1[600] #默认执行类中__delitem__方法,没有返回值 #输出: 还是方法:item:800 1800 1000 这就是第二种方法 600
class student: def __init__(self): self.hobby = 'pcgame' def __getitem__(self, item): print('还是方法:item:%s'%item) if type(item) == slice: print('切片处理') print(item.start) print(item.stop) print(item.step) else: print('索引处理') def __setitem__(self, key, value): print(key,value) def __delitem__(self, key): print(key) stu1 = student() stu1[800] #在类的对象后加上一个[]中括号,填上参数 stu1[1:5:4] #默认数据类型:slice #输出: 还是方法:item:800 索引处理 还是方法:item:slice(1, 5, 4) 切片处理 1 5 4
# class student: #声明一个类
# def show(self):
# pass
student = type('student',(object,),{'show1':lambda x:5}) #这也是声明了一个类
stu = student()
print(stu.show1())
#输出:
5
!!! 说明类在创建时使用了解释器内部默认的type类 !!!
那么我们可以利用继承,为type添加新功能,使得我们每次创建类时,都会调用该新功能
class mytype(type):
def __init__(self,*args,**kwargs):
print('添加新功能')
class student(object,metaclass=mytype):
def __init__(self):
pass
def show(self):
print('123')
#无需对象,默认自动调用type(mytype):
添加新功能
class mytype(type): def __init__(self,*args,**kwargs): #步骤二 pass #或者super().__init__() :执行父类的__init__()方法 def __call__(self, *args, **kwargs): #self:student stu = self.__new__() #步骤四 self.__init__(stu) #步骤六 class student(object,metaclass=mytype): #步骤一 def __init__(self): pass def __new__(cls, *args, **kwargs): return object.__new__(cls) #真正的创建对象 #步骤五 stu = student() #创建对象 #步骤三
步骤分析:
第一阶段:class student: #声明一个类
1.声明一个类时,首先将默认调用解释器中的type方法或上述继承至type的mytype方法中的__init__()方法。
第二阶段:stu = student() #创建一个类的对象
1.创建一个类的对象时,将会默认调用解释器中的type方法或上述继承至type的mytype方法中的__call__()方法。
2.调用__call__()方法中,对象self(此时的self是类:student)中的__new__()方法
3.类中的__new__()方法将会调用:object.__new__() 创建一个真正的类的对象,并返回对象数据给type或上述mytype中__call__方法中的stu
4.最后调用type或上述mytype中的__call__()方法中的self.__init__(stu),即调用声明的类中的__init__()方法,并将对象stu作为参数传入
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。