python (个人学习笔记2.0)--python中类与对象(简单梳理知识网络,以及部分深入理解)

前言

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

1.对象存数据 (对象向类内传入数据)(封装)

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

二、面对对象三大特性简述

1.封装

class teacher:
    def __init__(self,name,course):
        self.name = name
        self.course = course
        
teacher1 = teacher('王刚','高数')		#这是利用__init__()方法进行封装
teacher1.hobby = '篮球'		#这是封装

teacher2 = teacher('王李安','英语')
teacher2.hobby = '冲浪'

2.继承

继承运用: 不修改原类,为其添加新功能
代码编写应当遵循:开发封闭原则(修改禁止,添加扩展允许)

重写,超级

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
这是父方法
这是父方法

python中的多继承

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

3.多态

多态可以理解为定义多种数据类型,整型(int),字符型(string)等等。
在c,c++,java中,定义一个变量时,需要说明它的数据类型,而在python中,解释器将会根据运用自动判断其数据类型。
即:原生多态

三、字段和方法

1.字段

class ret:
	hobby = '网游' #静态字段,数据保存在类中,可以通过对象和类调用

	def __init__(self,name):
		self.name = name	#普通字段,数据保存在对象中,只能通过对象调用

son1 = ret('小明')
son1.name = '小刚'
ret.hobby  #son1.hobby

2.方法

class test:
	def ret1(self):			#普通方法
		print('没想到吧?')
		
	@staticmethod			#静态方法,由类直接调用
	def ret2():			#静态方法中,self将不再必须,即可以删掉self后,不传入参数,也可以自主定义传入参数
		print('这是静态方法')
	
t1 = test()

t1.ret1()	#对象调用普通方法		无论哪种调用方法,都需先创建一个对象
test.ret1(t1)	#类调用普通方法

test.ret2()	#类直接调用静态方法,不用传入对象

四、property,.setter,.deleter装饰器(为类的方法添加属性:三种调用方式)

1.

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
这是第三种调用方式

2.简化(效果等同)

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
这是私有方法

提要 :继承中,子类无法直接调用父类的私有变量和私有方法。

六、类的深入(特殊成员)

1. call与类的对象()

 lass student:
	def __init__(self):
		pass
	def __call__(self, *args, **kwargs):
		print('这是call方法')

stu1 = student()
stu1()			#在类对象后加上()括号,将自动调用类中的call方法

#输出:
这是call方法

2.int(),str()…与类

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

3.__dict__方法 (重要)

__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'}

4.1:__getitem____setitem____delitem 特殊成员方法

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

4.2 : 特殊成员getitem之:对象[ ] 切片与索引

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

5.类的声明–type

# 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):

添加新功能

6.深入了解类在创建对象时,默认自动执行__init__方法的原理

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作为参数传入
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值