本篇意为记录python学习过程
Python面向对象编程
python的特点就是面向对象,将对象及其使用的数据紧密联系,其他对象无法访问和调用其数据。和其他编程语言相比,python在尽可能不添加新的语法和机制的情况下加入了类机制,从而提供了面向对象编程的所有基本功能。
类的定义和使用
类的概念
类,用来描述一个具有相同属性和方法(函数)的对象的集合,同一类的所有对象拥有相同数量和形式的数据,这一点与结构体类似。同时,类的定义中所有方法(函数)都为该类的对象拥有。类的定义:
class people:
def prt(self):
print('hello')
类的使用
类对象支持两种操作实例化和属性引用。
实例化,即定义一个属于类的具体对象。
class people:
def prt(self):
print('hello')
x = people()
x.prt()
对象 x 即为属于 类:people 的对象。由上文类的概念可知 x 拥有类所定义的 prt() 函数,运行结果为:
类的方法和普通的函数唯一的区别——必须有一个额外的第一个参数,惯例定义为 self,也可以是 this,nowcoder
class Test:
def prt(self):
print(self)
print(self.__class__)
t = Test()
t.prt()
上述实例运行结果为:
<__main__.Test instance at 0x100771878>
__main__.Test
根据结果,Test instance(实例),后面是一串数字为实例对象的地址,可知。self代表的是类的实例,代表当前对象的地址,而self.class 指向类。
属性引用,类命名空间中所有的命名都是有效属性名。若类的命名如下:
class people:
name = 'OpenMV'
def prt(self):
print('hello')
#类的实例化
x = people()
#访问类的属性和方法
print('\n x的属性:', x.name)
print('\n x的方法:')
x.prt()
输出为:
init()构造方法
类有一个名为 init() 的特殊方法,该方法会在类的实例化操时自动引用。基本格式:
def __init__(self):
self.data = []
class people:
name = ''
def __init__(self):
self.name = 'OpenMV'
def prt(self):
print('hello')
x = people()
print(x.name)
运行结果为:
init函数也可以有参数,参数通过init()传递到类的实例化操作上,例如:
class Complex:
def __init__(self, realpart, imagpart):
self.r = realpart
self.i = imagpart
x = Complex(3.0, -4.5)
print(x.r, x.i) # 输出结果:3.0 -4.5
类的继承
python同样支持类的继承,派生类的定义如下:
class DerivedClassName(BaseClassName1):
<statement-1>
.
.
.
<statement-N>
多个基类继承时,需要注意圆括号中基类的顺序,若是基类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找基类中是否包含方法。
BaseClassName(示例中的基类名)必须与派生类定义在一个作用域内。除了类,还可以用表达式,基类定义在另一个模块中时这一点非常有用
class people:
name = ''
age = 0
def __init__(self, n, a):
self.name = n
self.age = a
def prt(self):
print("%s:hello, I'm %d years old" % (self.name, self.age))
class student(people):
grade = ''
def __init__(self, n, a, g):
# 调用父类的构造函数
people.__init__(self, n, a)
self.grade = g
# 覆写父类的方法
def prt(self):
print("%s:hello, I'm %d years old, I'm %s grade " % (self.name, self.age, self.grade))
x = student('openmv', 10, 'forth')
x.prt()
运行结果:
python同样支持多继承,形式
#类定义
class people:
#定义基本属性
name = ''
age = 0
#定义私有属性,私有属性在类外部无法直接进行访问
__weight = 0
#定义构造方法
def __init__(self,n,a,w):
self.name = n
self.age = a
self.__weight = w
def speak(self):
print("%s 说: 我 %d 岁。" %(self.name,self.age))
#单继承示例
class student(people):
grade = ''
def __init__(self,n,a,w,g):
#调用父类的构函
people.__init__(self,n,a,w)
self.grade = g
#覆写父类的方法
def speak(self):
print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))
#另一个类,多重继承之前的准备
class speaker():
topic = ''
name = ''
def __init__(self,n,t):
self.name = n
self.topic = t
def speak(self):
print("我叫 %s,我是一个演说家,我演讲的主题是 %s"%(self.name,self.topic))
#多重继承
class sample(speaker,student):
a =''
def __init__(self,n,a,w,g,t):
student.__init__(self,n,a,w,g)
speaker.__init__(self,n,t)
test = sample("Tim",25,80,4,"Python")
test.speak() #方法名同,默认调用的是在括号中排前地父类的方法
运行结果为:
我叫 Tim,我是一个演说家,我演讲的主题是 Python
方法重写
如果父类的方法无法完成子类的需求,可以在子类中对父类的方法进行重新,也就是在子类重新定义一个同名称的方法。
class Parent: # 定义父类
def myMethod(self):
print ('调用父类方法')
class Child(Parent): # 定义子类
def myMethod(self):
print ('调用子类方法')
c = Child() # 子类实例
c.myMethod() # 子类调用重写方法
super(Child,c).myMethod() #用子类对象调用父类已被覆盖的方法
super() 是用于调用父类的一个方法,运行结果为:
调用子类方法
调用父类方法
类的私有属性和专有方法
类的私有属性和方法
类的私有属性
__private_attrs:两个下划线开头,表明不能在类的外部使用或直接访问,使用时:self.__private_attrs
类的私有方法,同理
__private_method:两个下划线开头,表明不能在类的外部使用或直接访问,使用时:self.__private_method
类的专有方法
- init : 构造函数,在生成对象时调用
- del : 析构函数,释放对象时使用
- repr : 打印,转换
- setitem : 按照索引赋值
- getitem: 按照索引获取值
- len: 获得长度
- cmp: 比较运算
- call: 函数调用
- add: 加运算
- sub: 减运算
- mul: 乘运算
- truediv: 除运算
- mod: 求余运算
- pow: 乘方
资料参考: