Chapter6 面向对象编程
简介
创建一个“人类” 类
class HumanBeing():
def __init__(self,firstname,eyecolor):
self.firstname = firstname
self.eyecolor = eyecolor
self.position = 0
def walk(self,steps):
self.position += steps
Kim = HumanBeing("Kim","black")
Kim.position
0
Kim.firstname
'Kim'
Kim.walk(2000)
Kim.position
2000
一、看下Python对象
#从OOP的角度,分析了几个对象的性质(略)
二、Python类的基础
例子:考察FinancialInstrument类的一些性质
class FinancialInstrument(): #简记为FI类
pass
fi = FinancialInstrument() #根据FI类创建实例对象
type(fi)
__main__.FinancialInstrument
fi.__str__() #任何对象都具有的“特殊”方法 对象也是对象,它们本身也拥有方法和属性
'<__main__.FinancialInstrument object at 0x03B5A430>'
fi.price = 100 #对象的属性可以“动态”设置 (写程序会方便,但是会变得不稳定)
fi.price
100
fi.amount = 1200 #再动态设置一个属性
fi.amount
1200
例子1:
class FinancialInstrument:
author = "Kim"
def __init__(self,price,symbol): #初始化实例属性
self.price = price
self.symbol = symbol
FinancialInstrument.author #调用属性
'Kim'
appl = FinancialInstrument(100,"lala") #创建实例对象
appl.price
100
appl.symbol
'lala'
appl.price = 999 #给属性进行动态赋值
appl.price
999
例子(继承)2:
class FinancialInstrument(FinancialInstrument): #这两个FI本质就不一样的,前者继承后面的一切性质
#构建2个实例方法
def set_price(self,price):
self.price = price
def get_price(self):
return self.price
fi = FinancialInstrument(666,"appl")
fi.get_price()
666
fi.set_price(999)
fi.get_price()
999
例子3(封装):
#封装的原因:1)隐私问题:不想使用者过于详细发觉类中属性 2)担心用户使用时,不小心修改了类中属性
class FinancialInstrument:
def __init__(self,symbol,price):
self.symbol = symbol
self.__price = price #将价格这个属性,隐藏起来,这样就无法直接调用了; 术语:私有化实例属性
def get_price(self):
return self.__price
def set_price(self,price):
self.__price = price
fi = FinancialInstrument("appl",100)
fi.__price #无法直接查看
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-38-e3138907ce6c> in <module>
----> 1 fi.__price
AttributeError: 'FinancialInstrument' object has no attribute '__price'
fi.get_price() #调用方法进行查看
100
fi._FinancialInstrument__price #这样就可以查看了
100
例子4(可以将实例对象当做参数):
class PortPosition:
def __init__(self,financial_instru,position_size):
self.position = financial_instru
self.__position_size = position_size
def get_position_size(self):
return self.__position_size
def set_position_size(self,size):
self.__position_size = size
def get_position_value(self):
return self.position.get_price() * self.__position_size
pp = PortPosition(fi,100)
pp.get_position_size()
100
pp.position.get_price()
100
pp.get_position_value()
10000
pp.set_position_size(666)
pp.get_position_value() #体现了一个动态变化的过程
66600
三、Python数据模型
介绍数据模型的一些功能
例子(创建一个3维向量的类):
class Vector:
def __init__(self,x=0,y=0,z=0):
self.x = x
self.y = y
self.z = z
v = Vector(1,2,3)
v #这是没有添加 __repr__ 方法
<__main__.Vector at 0x3bc05f0>
class Vector(Vector):
def __repr__(self): #补充一个对 类对象 进行说明(打印)的方法,约定俗成的写法
return "Vector({0},{1},{2})".format(self.x,self.y,self.z)
v = Vector(1,1,1)
v #这是添加了 __repr__ 方法
Vector(1,1,1)
v.__str__() # 这也是调用 __repr__中的返回值
'Vector(1,1,1)'
例子(创建类方法):
abs 、 bool 方法
class Vector(Vector):
def __abs__(self):
return (self.x**2 + self.y**2 + self.z**2)**0.5
def __bool__(self):
return bool(abs(self))
v1 = Vector(1,2,3)
abs(v1)
3.7416573867739413
bool(v1)
True
v2 = Vector()
bool(v2)
False
#注意: bool abs 这些是Python的内置方法 当里面参数类型不是Vector对象时:执行之前的功能
# 当里面参数是Vector对象时: 调用类中定义的功能
add/mul 方法
class Vector(Vector):
def __add__(self,other):
x = self.x + other.x
y = self.y + other.y
z = self.z + other.z
return Vector(x,y,z)
Vector(1,2,3) + Vector(6,6,6) #"+" 就是调用 add方法!
Vector(7,8,9)
class Vector(Vector):
def __mul__(self,scalar):
return Vector(self.x*scalar,self.y*scalar,self.z*scalar)
Vector(1,2,3) * 2
Vevtor(2,4,6)
len / getitem 方法
class Vector(Vector):
def __len__(self):
return 3 #3维向量里面的元素个数,肯定是3个
def __getitem__(self,i): #本质上就是[] 索引
if i in [0,-3] : return self.x
elif i in [1,-2] : return self.y
elif i in [2,-1] : return self.z
else: raise IndexError("超出索引范围") #这是error对象
v3 = Vector(1,2,3)
len(v3)
3
v3[2]
3
v3[88]
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-113-3225efcdf95d> in <module>
----> 1 v3[88]
<ipython-input-109-9f7b92dca6e2> in __getitem__(self, i)
6 elif i in [1,-2] : return self.y
7 elif i in [2,-1] : return self.z
----> 8 else: raise IndexError("超出索引范围")
IndexError: 超出索引范围
iter 迭代方法
#对于yield、迭代与iterable的概念可以看这里(如有侵权请联系本人):
https://blog.csdn.net/u011318077/article/details/93749143
例子:
class Vector(Vector):
def __iter__(self):
for i in range(len(self)):
yield self[i] #形成可迭代的生成器
v = Vector(1,2,3)
for i in v:
print(i)
1
2
3
四、Vector类
#就是将上面对于Vector的定义封装在一整块区域之中
class Vector:
def __init__(self,x=0,y=0,z=0): #初始化实例属性
self.x = x
self.y = y
self.z = z
def __repr__(self): #返回对于对象的描述,返回值类型为字符串
return "Vector({0},{1},{2})".format(self.x,self.y,selg.z)
def __abs__(self):
return (self.x**2 + self.y**2 +self.z**2)**0.5
def __bool__(self):
return bool(abs(self))
def __len__(self):
return 3
def __add__(self,other):
x = self.x + other.x
y = self.y + other.y
z = self.z + other.z
return Vector(x,y,z)
def __mul__(self,scalar):
x = self.x * scalar
y = self.y * scalar
z = self.z * scalar
return Vector(x,y,z)
def __getitem__(self):
if i in [0,-3]: return self.x
elif i in [1,-2]: return self.y
elif i in [2,-1]: return self.z
else: raise IndexError("超出索引范围")
def __iter__(self):
for i in range(len(self)):
yield self[i]
五、总结
#通过例子,简单介绍OOP的一些概念