python学习(五) 类和魔法方法

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()__,下面介绍其他的魔法方法

  1. __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)
  1. __del__
    对象被回收时调用
    def __del__(self):
       print("delete NewInt", self)

在上面的NewInt类扩展的部分,程序退出时可以看到调用__del__

  1. 算数运算
    算术运算相关魔法方法
__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
  1. __str__
    类表现,改变/新增打印的方法
	def __str__(self):
        return "NewInt : %d" % self
  1. 属性相关魔法方法
__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
  1. 描述符
    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
  1. 迭代器
    迭代器的魔法方法
__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可以作为类的初始化变量,再进行更改

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值