Python学习打call第三十天:魔术方法

今天我们学习魔术方法,听这个名字我们可能完全不知道这是个什么,其实魔术方法就是在我们定义的类中定义一些”不一般”的方法,使类的使用更方便、完善、健壮,是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__()调用

很明显可以看出,先调用了__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中,实现了call方法的对象都是可调用对象;

  • __call__:允许一个类的实例像函数一样被调用:x(a, b)调用为 x.__call__(a, b)

更多魔术方法的详情可以参考python官网:https://docs.python.org/3/reference/datamodel.html
学习视频:https://www.9xkd.com/user/plan-view.html?id=3623904578

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,036评论 1 32
  • 不用Ajax还有其他的方法来做交互嘛
    YourVictory阅读 1,730评论 0 0
  • 前世佛前 你是那片摇曳的火焰 而我就是那盏青灯 谁说了 孤灯清盏 我就喜欢这份 相守的宁静 我用一生的时光守望 凝...
    一颗浮萍阅读 299评论 2 4