Python之魔术方法

242 篇文章 10 订阅
216 篇文章 2 订阅

今天我们学习魔术方法,听这个名字我们可能完全不知道这是个什么,其实魔术方法就是在我们定义的类中定义一些”不一般”的方法,使类的使用更方便、完善、健壮,是python特有的方法,一般都是前后包含两个下划线__的方法称为魔术方法,例如__new__

基本魔术方法有哪些

__new__:是在一个对象实例化的时候所调用的第一个方法,用来创建类并返回这个类的实例;

class Student:
    def __init__(self):
        print("__init__()调用")

    def __new__(cls, *args, **kwargs):
        print('__new__()调用, {cls}'.format(cls=cls))
        return object.__new__(cls, *args, **kwargs)

stu = Student()

# 输出结果:
__new__()调用, <class '__main__.Student'>
__init__()调用

如果你依然在编程的世界里迷茫,
不知道自己的未来规划,
对python感兴趣,
这里推荐一下我的学习交流圈QQ群:895 797 751,
里面都是学习python的,

  • 很明显可以看出,先调用了__new__方法,然后调用了__init__方法

  • init:构造器,是一个初始化方法,在一个实例被创建之后调用;

  • del:析构器,当一个实例被销毁的时候调用的方法;

  • bool:如果对象实现了bool方法,那么返回结果,非0为真,如果没有实现bool方法,调用len方法,返回非0为真;

  • hash:返回一个整数,表明对象可以hash;

  • repr:返回对象的字符串表达式,如果没有实现,直接返回对象内存地址字符串;

  • str:str()、print()、format()函数打印对象字符串,会直接调用str方法,如果没有实现,会调用repr方法;

  • hash:定义当被 hash() 调用时的行为;

  • bytes:定义当被 bytes() 调用时的行为;

  • format:定义当被 format() 调用时的行为;

有关属性魔术方法有哪些

  • getattr:定义当用户试图获取一个不存在的属性时的行为;
  • setattr:定义当一个属性被设置时的行为;
  • getattribute:定义当该类的属性被访问时的行为;
  • delattr:删除一个属性时执行的方法;
  • dir:定义当 dir() 被调用时的行为;
  • get:定义当描述符的值被取得时的行为;
  • set:定义当描述符的值被改变时的行为;
  • delete:定义当描述符的值被删除时的行为;

运算符相关魔术方法有哪些

我们通过一小实例来看一下,有关于运算符相关的魔术方法的使用

class Student:
    def __init__(self, x):
        self.x = x

    def __add__(self, other):
        return self.x + other.x

    def __sub__(self, other):
        return self.x - other.x

    def __mul__(self, other):
        return self.x * other.x

a = Student(1)
b = Student(2)
c = Student(3)
print(b-a)  # 输出:1
print(b+a)  # 输出:3
print(b*c)  # 输出:6

  • add:定义加法的方法;
  • sub:定义减法的方法;
  • mul:定义乘法的方法;
  • truediv:定义除法的方法;
  • floordiv:定义整数除法的行为://;
  • mod:定义取模算法的行为:%;
  • divmod:定义当被 divmod() 调用时的行为;
  • pow:定义当被 power() 调用或 ** 运算时的行为;
  • lshift:定义按位左移位的行为:<<;
  • rshift:定义按位右移位的行为:>>;
  • and:定义按位与操作的行为:&;
  • xor:定义按位异或操作的行为:^;
  • or:定义按位或操作的行为:|;

比较操作符相关魔术方法有哪些

  • 有关于比较操作符的魔术方法也有很多,下面例子中有__eq__和__lt__的举例,大家自己动手把所有的方法都操作一遍,就能很快理解操作符相关魔术方法的使用了
class Student(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def __eq__(self, other):
        return True if self.a == other.a else False

    def __lt__(self, other):
        if self.a < other.a:
            return True
        else:
            return False

stu1 = Student(1, 2, 3)
stu2 = Student(3, 2, 1)
stu3 = Student(1, 2, 3)

print(stu1 == stu2)   # 输出:False
print(stu1 == stu3)   # 输出:True

print(stu1 < stu2)    # 输出:True
print(stu1 < stu3)    # 输出:False


  • eq:定义等于号的方法,等价于==;
  • lt:定义小于号方法,等价于<;
  • gt:定义大于号方法,等价于>;
  • le:定义小于等于号的行为,等价于 <= ;
  • ne:定义不等号的行为,等价于!= ;
  • ge:定义大于等于号的行为,等价于 >= ;

容器相关的魔术方法有哪些

class Student:
    def __init__(self):
        self.items = {}

    def __len__(self):
        return len(self.items)

    # 如果stu.items不为空,返回True
    def __bool__(self):
        return True if len(self) else False

    def __iter__(self):
        return iter(self.items)

    def __getitem__(self, item):
        return self.items[item]

    def __setitem__(self, key, value):
        self.items[key] = value

stu= Student()

stu.items['Course'] = 'Python'
stu.items['Teacher'] = '张三'
print(len(stu))

print(bool(stu))
print(iter(stu))
print(stu['Course'])

stu['Course'] = 'HTML'
print(stu['Course'])
  • len:定义当被 len() 调用时的行为(返回容器中元素的个数);
  • iter:定义当迭代容器中的元素的行为;
  • getitem:获取容器中的元素,相当于 self[key];
  • setitem:设置容器中的元素,相当于 self[key] = value;
  • delitem:删除容器中的某个元素,相当于 del self[key];
  • reversed:定义当被 reversed() 调用时的行为;
  • contains:定义当使用成员测试运算符(in 或 not in)时的行为;

可调用对象

# 函数是可调用对象
def add():
    pass

add.__call__()
add()

# 类实现了__call__方法
class Add():
    def __call__(self, *args, **kwargs):
        print(args)
        print(kwargs)

add_instance = Add()

add_instance.__call__(1,2,3, course='Python')

add_instance(1,2,3,course='Python')

如果你依然在编程的世界里迷茫,
不知道自己的未来规划,
对python感兴趣,
这里推荐一下我的学习交流圈QQ群:895 797 751,
里面都是学习python的,
  • Python中,实现了call方法的对象都是可调用对象;
  • call:允许一个类的实例像函数一样被调用:x(a, b)调用为 x.call(a, b);

更多魔术方法的详情可以参考python官网:https://docs.python.org/3/reference/datamodel.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值