共计 3370 个字符,预计需要花费 9 分钟才能阅读完成。
本文来说说 Python 中的类与对象,Python 这门语言是无处不对象,如果你曾浅要理解过 Python,你应该听过 Python 是一种面向对象编程的语言,所以你常常可能会看到面向“对象”编程这类段子,而面向对象编程的语言都会有三大特色:封装、继承、多态。
咱们平时接触到的很多函数、办法的操作都具备这些性质,咱们只是会用,但还没有去深刻理解它的实质,上面就介绍一下对于类和对象的相干常识。
封装
封装这个概念应该并不生疏,比方咱们把一些数据封装成一个列表,这就属于数据封装,咱们也能够将一些代码语句封装成一个函数不便调用,这就是代码的封装,咱们也能够将数据和代码封装在一起。用术语示意的话,就是能够将属性和办法进行封装,从而失去对象。
首先咱们能够定义一个类,这个类中有属性和办法,但有的搭档会比拟好奇,属性和办法不是会封装成对象嘛,为什么又变成类了?举个例子,类就好比是一个毛坯房,而对象是在毛坯房的根底上革新成的简装房。
class XiaoMing:
#属性
height = 180
weight = 65
sex = '男'
#办法
def run(self):
print('小明在跑步')
def sleep(self):
print('小明在睡觉')
在类定义实现时就创立了一个类对象,它是对类定义创立的命名空间进行了一个包装。类对象反对两种操作:属性援用和实例化。
属性援用的语法就是个别的规范语法:obj.name。比方 XiaoMing.height 和 XiaoMing.run 就是属性援用,前者会返回一条数据,而后者会返回一个办法对象。
In[1]:print(XiaoMing.height)
Out[1]:180
In[2]:print(XiaoMing.run)
Out[2]:<function XiaoMing.run at 0x0000021C6239D0D0>
这里也反对对类属性进行赋值操作,比方为类中的 weight 属性赋予一个新值。
In[3]:print(XiaoMing.weight)
Out[3]:65
In[4]:XiaoMing.weight = 100
In[5]:print(XiaoMing.weight)
Out[5]:100
而类的实例化能够将类对象看作成一个无参函数的赋值给一个局部变量,如下:
In[6]:ming = XiaoMing()
ming 就是由类对象实例化后创立的一个实例对象,通过实例对象也能够调用类中的属性和办法。
In[7]:ming.run()
Out[7]: 小明在跑步
In[8]:print(xiaoming.height)
Out[8]:180
#通过向类对象调用办法返回的办法对象中传入实例对象也能够达到同样成果
In[11]:XiaoMing.run(ming)
Out[11]: 小明在跑步
魔法办法__init__
类在实例化过程中并不都是像下面例子一样简略的,个别类都会偏向将实例对象创立为有初始状态的,所以在类中可能会定义一个__init__的魔法办法,这个办法就能够帮忙接管、传入参数。
而一个类如果定义了__init__办法,那么在类对象实例化的过程中就会主动为新创建的实例化对象调用__init__办法,请看上面这个例子。
class Coordinates:
def __init__(self,x,y):
self.x = x
self.y = y
def print_coor(self):
print('以后坐标为 (%s,%s)'%(self.x,self.y))
能够看到在__init__() 中传入了参数 x 和 y,而后在 print_coor 中须要接管参数 x 和 y,接下来通过实例化这个类对象,验证一下参数是否能通过__init__() 传递到类的实例化操作中。
In[9]:coor = Coordinates(5,3)
In[10]:coor.print_coor()
Out[10]: 以后坐标为 (5,3)
继承
所谓继承就是一个新类在另一个类的根底上构建而成,这个新类被称作子类或者派生类,而另一个类被称作父类、基类或者超类,而子类会继承父类中已有的一些属性和办法。
class Mylist(list):
pass
list_ = Mylist()
list_.append(1)
print(list_)
'''[1]'''
比方下面这个例子,我并没有将 list_定义成一个列表,但它却能调用 append 办法。起因是类 Mylist 继承于 list 这个基类,而 list_又是 Mylist 的一个实例化对象,所以 list_也会领有父类 list 领有的办法。当然能够通过自定义类的模式实现两个类之间的继承关系,咱们定义 Parent 和 Child 两个类,Child 中没有任何属性和办法,只是继承于父类 Parent。
class Parent:
def par(self):
print('父类办法')
class Child(Parent):
pass
child = Child()
child.par()
'''父类办法'''
笼罩
当子类中定义了与父类中同名的办法或者属性,则会主动笼罩父类对应的办法或属性,还是用下面这个例子实现一下,不便了解。
class Parent:
def par(self):
print('父类办法')
class Child(Parent):
def par(self):
print('子类办法')
child = Child()
child.par()
'''子类办法'''
能够看到子类 Child 中多了一个和父类 Parent 同名的办法,再实例化子类并调用这个办法时,最初调用的是子类中的办法。Python 中继承也容许多重继承,也就是说一个子类能够继承多个父类中的属性和办法,然而这类操作会导致代码凌乱,所以大多数状况下不举荐应用,这里就不过多介绍了。
多态
多态比较简单,比方定义两个类,这两个类没有任何关系,只是两个类中有同名的办法,而当两个类的实例对象别离调用这个办法时,不同类的实例对象调用的办法也是不同的。
class XiaoMing:
def introduce(self):
print("我是小明")
class XiaoHong:
def introduce(self):
print("我是小红")
下面这两个类中都有 introduce 办法,咱们能够实例化一下两个类,利用实例对象调用这个办法实现一下多态。
In[12]:ming = XiaoMing()
In[13]:hong = XiaoHong()
In[14]:ming.introduce()
Out[14]: 我是小明
In[15]:hong.introduce()
Out[15]: 我是小红
罕用 BIF
1、isssubclass(class,classinfo)
判断一个类是否是另一个类的子类,如果是则返回 True,反之则返回 False。
class Parent:
pass
class Child(Parent):
pass
print(issubclass(Child,Parent))
'''True'''
须要留神的有两点:
- 1. 第二个参数不仅能够传入类,也能够传入由类组成的元组。
-
2. 一个类被断定为本身的子类,也就是说这两个参数传入同一个类时,也会返回 True。
print(issubclass(Parent,Parent)) '''True'''
2、isinstance(object,classinfo)
判断一个对象是否为一个类的实例对象,如果是则返回 True,反之则返回 False。
class Parent: pass class Child: pass p = Parent() c = Child() print(isinstance(p,Parent,Child)) #True print(isinstance(c,Parent)) #False
须要留神的有两点:
- 1. 第二个参数不仅能够传入类,也能够传入由类组成的元组。
- 2. 如果第一个参数传入的不是一个对象,则总是返回 False。
3、hasattr(object,name)
判断一个实例对象中是否蕴含一个属性,如果是则返回 True,反之则返回 False。
class Parent:
height = 100
p = Parent()
print(hasattr(p,'height'))
'''True'''
须要留神的是第二个参数 name 必须为字符串模式传入,如果不是则会返回 False。