PythonStudy——魔法函数 Magic Methods

Stella981
• 阅读 487

魔法函数

  • python中以双下划线开始和结束的函数(不可自己定义)为魔法函数
  • 调用类实例化的对象的方法时自动调用魔法函数(感觉不需要显示调用的函数都叫)
  • 在自己定义的类中,可以实现之前的内置函数,比如下面比较元素sorted时用It函数(lt(self, other):判断self对象是否小于other对象;)

PythonStudy——魔法函数  Magic Methods

class MyVector(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, other_instance):
        re_vector = MyVector(self.x+other_instance.x, self.y+other_instance.y)
        return re_vector

    def __str__(self):
        return"x:{x}, y:{y}".format(x=self.x, y=self.y)


first_vec = MyVector(1,2)
second_vec = MyVector(2,3)
print(first_vec+second_vec)

PythonStudy——魔法函数  Magic Methods

操作符重载:通过定义类的一些约定的以"__"开头并结尾的函数,可以到达重载一些特定操作的目的

__str__ / __unicode__
当print一个对象实例时,实际是print该实例 .str()函数的返回值:

class A:
    def __str__(self):
        return "A"
    def __unicode__(self):
        return "uA"

魔法函数有什么作用?

魔法函数可以为你写的类增加一些额外功能,方便使用者理解。举个简单的例子,我们定义一个“人”的类People,当中有属性姓名name、年龄age。让你需要利用sorted函数对一个People的数组进行排序,排序规则是按照name和age同时排序,即name不同时比较name,相同时比较age。由于People类本身不具有比较功能,所以需要自定义,你可以这么定义People类:

PythonStudy——魔法函数  Magic Methods

class People(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
        return

    def __str__(self):
        return self.name + ":" + str(self.age)

    def __lt__(self, other):
        return self.name < other.name if self.name != other.name else self.age < other.age




if __name__=="__main__":

    print("\t".join([str(item) for item in sorted([People("abc", 18), People("abe", 19), People("abe", 12), People("abc", 17)])]))

PythonStudy——魔法函数  Magic Methods

  • 上个例子中的__lt__函数即less than函数,即当比较两个People实例时自动调用。

Python中有哪些魔法函数?

Python中每个魔法函数都对应了一个Python内置函数或操作,比如__str__对应str函数,__lt__对应小于号<等。Python中的魔法函数可以大概分为以下几类:

类的构造、删除:

object.__new__(self, ...) object.__init__(self, ...) object.__del__(self)

二元操作符:

+ object.__add__(self, other) - object.__sub__(self, other) * object.__mul__(self, other) // object.__floordiv__(self, other) / object.__div__(self, other) % object.__mod__(self, other) ** object.__pow__(self, other[, modulo]) << object.__lshift__(self, other) >> object.__rshift__(self, other) & object.__and__(self, other) ^ object.__xor__(self, other) | object.__or__(self, other)

扩展二元操作符:

+= object.__iadd__(self, other) -= object.__isub__(self, other) *= object.__imul__(self, other) /= object.__idiv__(self, other) //= object.__ifloordiv__(self, other) %= object.__imod__(self, other) **= object.__ipow__(self, other[, modulo]) <<= object.__ilshift__(self, other) >>= object.__irshift__(self, other) &= object.__iand__(self, other) ^= object.__ixor__(self, other) |= object.__ior__(self, other)

一元操作符:

- object.__neg__(self) + object.__pos__(self) abs() object.__abs__(self) ~ object.__invert__(self) complex() object.__complex__(self) int() object.__int__(self) long() object.__long__(self) float() object.__float__(self) oct() object.__oct__(self) hex() object.__hex__(self) round() object.__round__(self, n) floor() object__floor__(self) ceil() object.__ceil__(self) trunc() object.__trunc__(self)

比较函数:

< object.__lt__(self, other) <= object.__le__(self, other) == object.__eq__(self, other) != object.__ne__(self, other) >= object.__ge__(self, other) > object.__gt__(self, other)

类的表示、输出:

str() object.__str__(self) repr() object.__repr__(self) len() object.__len__(self) hash() object.__hash__(self) bool() object.__nonzero__(self) dir() object.__dir__(self) sys.getsizeof() object.__sizeof__(self)

类容器:

len() object.__len__(self) self[key] object.__getitem__(self, key) self[key] = value object.__setitem__(self, key, value) del[key] object.__delitem__(self, key) iter() object.__iter__(self) reversed() object.__reversed__(self) in操作 object.__contains__(self, item) 字典key不存在时 object.__missing__(self, key)

点赞
收藏
评论区
推荐文章
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
C++中基类虚析构函数的作用及其原理分析
虚析构函数的理论前提是执行完子类的析构函数,那么父类的虚构函数必然会被执行。那么当用delete释放一个父类指针所实例化的子类对象时,如果没有定义虚析构函数,那么将只会调用父类的析构函数,而不会调用子类的虚构函数,导致内存的泄漏。故: 继承时,要养成的一个好习惯就是,基类析构函数中,加上virtual。知识背景     
Stella981 Stella981
2年前
Python基础(六)
1函数1.1函数的分类函数可以分成三种:内置函数(BIF):解释器中内置的函数,可以直接通过函数名调用,如len().模块函数:定义在模块中的函数,通过模块名调用,如math.sin().用户自定义函数.1.2函数与方法函数是指在类外定义的,可以独立调用的
Stella981 Stella981
2年前
JS 对象数组Array 根据对象object key的值排序sort,很风骚哦
有个js对象数组varary\{id:1,name:"b"},{id:2,name:"b"}\需求是根据name或者id的值来排序,这里有个风骚的函数函数定义:function keysrt(key,desc) {  return function(a,b){    return desc ? ~~(ak
Stella981 Stella981
2年前
JS 中的this指向问题和call、apply、bind的区别
this的指向问题一般情况下this对象指向调用函数的对象,全局环境中执行函数this对象指向window。functiona(){console.log(this);//输出函数a中的this对象}functionb(){};varc{name:"call"}
Wesley13 Wesley13
2年前
C++ 什么时候调用析构函数
析构函数是在对象消亡时,自动被调用,用来释放对象占用的空间。有四种方式会调用析构函数:1.生命周期:对象生命周期结束,会调用析构函数。2.delete:调用delete,会删除指针类对象。3.包含关系:对象Dog是对象Person的成员,Person的析构函数被调用时,对象Dog的析构函数也被调用。4.
Stella981 Stella981
2年前
Python中函数和方法的区别
1、函数要手动传self,方法不用传self2、如果是一个函数,用类名去调用,如果是一个方法,用对象去调用 举例说明:classFoo(object):def__init__(self):self.name"haiyan"deffunc(self):
Wesley13 Wesley13
2年前
C++错误收集(2)
ERRORNO.2内置函数inline。类体中定义的函数功能一般规模较小,系统调用类为定义的函数的过程需要的时间开销是比较大的,为了减少系统调用函数的时间开销,如果在类体智能光定义的函数不包括循环等控制结构,C会自动将它们作为内置函数。内置函数的作用是将函数实现的代码替代声明的地方,以减小系统调用类外函数的时间开销。今天使用是遇到了问题
Stella981 Stella981
2年前
CI等MVC框架中为什么不能有index控制器的原因
因为类名称是index而方法又是index,这样index函数就是php4中的构造函数,即实例化类时,直接执行这个函数而没有执行父类的构造函数,也就没有初始化CI核心类。所以会提示没有定义属性或方法了。用index类名也可以,在publicfunctionindex()方法前加上,调用父类的构造方法publicfunction\_\
Wesley13 Wesley13
2年前
VC++知识点整理
1.内联函数定义:定义在类体内的成员函数,即函数的函数体放在类体内特点:在调用处用内联函数体的代码来替换,用于解决程序的运行效率问题。一定要在调用之前定义,并且内联函数无法递归调用。2.构造函数与析构函数构造函数:用于为对象分配内存空间,对类的成员变量进行初始化,并执行其他内部管理操作。可以接受参