类
python的类用class [类名]: 来定义
定义类中方法,需要引用到对象的参数需要self参数,类似于C++的this
构造方法 __init__() 实际是一个魔法方法,在对象创建时会自动调用
私有值可以用 "__valuename"实现,不过实际是伪私有,可以通过“_类__valuename"访问
继承类的方法 class 类(被继承类):
下面是类的一个应用示例,供学习参考
class Circle:
"""this is a class for storing circle, with only radius as its param"""
def __init__(self, radius=0):
self.radius = radius
def area(self):
return self.radius * self.radius * 3.14
def get_radius(self):
return self.radius
def set_radius(self, value):
self.radius = value
def del_size(self):
del self.radius
# 通过属性设置属性,外部调用时接口固定
x = property(get_radius, set_radius, del_size)
class Cylindar(Circle):
def __init__(self, height=0, radius=0):
# 注意被继承类的初始化,可以用下面两种方法进行
# Circle.__init__(radius)
super().__init__(radius)
self.height = height
def volume(self):
return self.area() * self.height
class Geometry:
def __init__(self, radius=0, height=0):
self.circle = Circle(radius=radius)
self.cylindar = Cylindar(height=height,radius=radius)
def print_area(self):
print("circle area is : ", self.circle.area())
print("Cylindar volume is : ", self.cylindar.volume())
if __name__ == '__main__':
c = Circle(5)
print(c.radius)
print(c.area())
d = Cylindar(height=5,radius=3)
# d.radius = 3
print(d.volume())
print(d.area())
g = Geometry(3, 5)
g.print_area()
魔法方法
上面类初始化时已经使用过一个魔法方法__init()__,下面介绍其他的魔法方法
- __new__
通常不去重写,一般在类继承了一个不可变类型,如str,int,list等,去进行重写
class NewInt(int):
def __new__(cls, integer):
integer = integer * integer
return int.__new__(cls, integer)
if __name__ == '__main__':
a = NewInt(2)
print(a)
- __del__
对象被回收时调用
def __del__(self):
print("delete NewInt", self)
在上面的NewInt类扩展的部分,程序退出时可以看到调用__del__
- 算数运算
算术运算相关魔法方法
__add__(self,other)
__sub__(self,other)
__mul__(self,other)
__truediv__(self,other)
__floordiv__(self,other)
__mod__(self,other)
__divmod__(self,other)
__pow__(self,other)
__lshift__(self,other)
__rshift__(self,other)
__and__(self,other)
__xor__(self,other)
__or__(self,other)
继续在NewInt中添加
def __add__(self, other):
return int(self) + int(other)#这里小心,不要写出无限递归来!!
这样NewInt之间可以进行加法运算了
双目运算符的情况有交换律,而有可能在运算时,没有定义__add__
可以对反运算的函数进行定义:__radd__
class NewInt(int):
def __new__(cls, integer):
integer = integer * integer
return int.__new__(cls, integer)
def __del__(self):
print("delete NewInt", self)
def __add__(self, other):
return int(self) + int(other)
def __radd__(self, other):
return int(self) * 2 + other
if __name__ == '__main__':
a = NewInt(2)
print(a)
b = NewInt(4)
print(b + 1) #17
print(1 + b) #33
- __str__
类表现,改变/新增打印的方法
def __str__(self):
return "NewInt : %d" % self
- 属性相关魔法方法
__getattr__
__getattribute__
__setattr__
__delattr__
# def NewInt():
# ...
def __getattr__(self, item):
print("using getattr")
def __getattribute__(self, item):
print("in __getattribute__")
return super().__getattribute__(item)
a = NewInt(2)
a.y#相当于去类中获取这个属性,调用__getattribute__
# in __getattribute__
# using getattr
- 描述符
property类似原理
class MyProperty: #相当于构建了一个描述符
def __init__(self, fget = None, fset = None, fdel = None):
self.fget = fget
self.fset = fset
self.fdel = fdel
def __get__(self, instance, owner):
print("my property get")
return self.fget(instance)
def __set__(self, instance, value):
print("my property set")
self.fset(instance, value)
def __delete__(self, instance):
print("my property del")
self.fdel(instance)
class Test:
def __init__(self):
self._x = None
def get(self):
return self._x
def set(self, value):
self._x = value
def dele(self):
del self._x
x = MyProperty(get, set, dele)
if __name__ == '__main__':
t = Test()
t.x = 5
print(t.x)
del t.x
- 迭代器
迭代器的魔法方法
__iter__
__next__
用迭代器实现一个Fibonacci序列
class Fibs:
def __init__(self):
self.a = 0
self.b = 1
def __iter__(self):
return self
def __next__(self):
self.a, self.b = self.b, self.a+self.b
return self.a
if __name__ == '__main__':
f = Fibs()
for e in f:
if e > 35:
break
else:
print(e)
迭代器的Next在没有值可以返回,或者抛出一个异常
raise StopIteration
可以结束迭代
稍作修改
def __next__(self):
self.a, self.b = self.b, self.a+self.b
if self.a > 20:
raise StopIteration
return self.a
输出到13就结束了,20可以作为类的初始化变量,再进行更改