美文网首页Python
Python中常用的魔术方法

Python中常用的魔术方法

作者: 小啊小狼 | 来源:发表于2020-10-13 09:54 被阅读0次

什么是魔术方法

python类中有一些方法前后都有两个下划线,这类函数统称为魔术方法。这些方法有特殊的用途,有的不需要我们自己定义,有的则通过一些简单的定义可以实现比较神奇的功能

常用魔术方法

1、不需要修改直接调用

__dict__ :类和实例都可以调用这个方法

  • 类调用返回这个类中已经定义了的属性和方法,包括特殊方法
  • 实例调用返回属性的字典
class MyTest:
    """自定的类:文档注释"""
    name = 'myclass类'
    def __init__(self, age):
        self.age = age
    def func(self):
        print('func')
print(MyTest.__dict__)
m = MyTest(18)
print(m.__dict__)

#输出
{'__module__': '__main__', '__doc__': '自定的类:文档注释', 'name': 'myclass类', '__init__': <function MyTest.__init__ at 0x0000020182F947B8>, 'func': <function MyTest.func at 0x000002018367D158>, '__dict__': <attribute '__dict__' of 'MyTest' objects>, '__weakref__': <attribute '__weakref__' of 'MyTest' objects>}
{'age': 18}

__module__ :类和实例都可以调用,类所在的模块,比如aa文件夹下的bb.py文件中则返回 aa.bb
__class__ :只有实例可以调用,表明实例属于哪个类,内容包括了__module__的信息
dir()函数 作用于类和实例上,返回它所有的属性和方法,实际上相当于调用了__dir__()函数

2、可以进行简单定义之后使用的方法

__doc__ 返回定义类时标注的字符串,标注位置必须在定义的方法属性之前,默认是None

__init__ :类创建对象的时候会触发,初始化函数,用于定义实例属性

__call__ :可以让对象像函数一样调用(对象加括号去调用的时候会出触发)

__str__ :print实例时打印出来的内容,不定义可以调用,重新定义后则可以定制打印内容,该方法决定对象被print打印的时候,显示的内容

__repr__ 直接输出实例名打印出来的内容,不定义可以调用,重新定义后则可以定制打印内容

__new__ :在通过类创建对象的时候调用!(python中所有类默认都是继承object类)

__len__ 定义 len(实例) 返回的内容,比如字符串类就定义的是字符串的字符个数,当然也可以改成其他的

__eq__ 改变==运算符的行为,定义实例使用==number时,是拿实例的什么与number相比
和eq类似的还有ne lt le gt ge
还有一些用于实例之间数值计算的 add abs等方法,定义方式和eq差不多,这些应用的典型类就是数值类,定义这些其实定义了某些运算符的行为,比如iadd定义了+=的行为一样。除此之外还有转化为整数、浮点,

__slots__ = ('name', 'age') 加一句这个可以只允许定义这两个属性,无法在实例中添加,这条命令只对当前类起作用,对子类无效

  • 1、可以覆盖dict属性:只要这个类定义了__slots__这个属性,python就不会给这个类添加dict
    • __slots__ = ['age', 'name', 'gender']
    • 列表形式定义了__slots__,就只能给这个类设置限定的几个属性
  • 2、可以限制这个类对对象,属性的绑定

应用场景
1、定义的类需要创建大量的对象。可以通过__slots__ 来指定对象属性,覆盖__dict__,减少内存开销
2、要限定这个类的对象绑定的属性

__getattr__ 当实例访问的属性未被定义时,原来会报错,定义了这个之后就会按照这里定义的来输出. setattr 则可以设置属性 delattr则删除属性
用法展示

class Special:
    '''描述类的信息,__doc__返回放在这里的字符串结果'''
    
    __slots__ = ('name', 'age','__weight') # 限制属性的取值
    
    def __init__(self, name, age, weight):
        self.name = name
        self.age = age
        self.__weight = weight
    
    def __call__(self, content): # 定义 实例() 会返回什么结果
        print(content)
        
    def __str__(self): # 定义打印实例会返回什么结果
        return 'Special object (name:%s)' % self.name
    
    __repr__ = __str__  # 这样简单赋值即可
    
    def __len__(self): # 定义len函数返回的结果
        return len(self.name)
    
    def __eq__(self, num): # 实例和数字比
        return len(self.name) == num
    
    def __gt__(self, other): # 这样可以实现实例和实例比
        return len(self.name) >= len(other)
    
    def __getattr__(self, attr):
        if attr=='score':
            return "You can't see the score"

创建实例

s = Special("Bob", 5, 4)
# s.hobby = "running" # 报错,因为__slots__限制了属性取值
s.__doc__ # 返回类定义时下方写的字符串描述内容
# '描述类的信息,__doc__返回放在这里的字符串结果'
s("__call__ is used") # 调用了__call__
# __call__ is used
print(s) # 调用__str__
# Special object (name:Bob)
s # 调用__repr__
# Special object (name:Bob)
len(s) # 调用了__len__
# 3
s==3 # 调用了__eq__
# True
Special("Mary", 4,5) > Special("Bob",5,4) # 调用__gt__
# True
s.score # 无score参数,调用__getattr__
# "You can't see the score"

3、可迭代对象所拥有的的魔术方法

使实例成为可迭代对象(可以被for循环的)

  • 实现 __iter__和__next__ 方法
  • 如果只实现__iter__则这个方法的返回值必须是一个迭代器

原理是当对实例调用for循环时,相当于每次对iter的返回结果作用一次next()函数,所以要想迭代必须定义iter方法。第一种就是next每次正常调用iter返回的值,这就要求它的返回值是一个迭代器;第二种则是把next函数改掉,使其功能不再是找到下一个,而是定制我们想要的一些操作

第一种

class Ite1:
    
    def __init__(self, a):
        self.a = a
        
    def __iter__(self):
        return iter(range(2*self.a)) # iter函数将一个可迭代对象变成迭代器
     
i1 = Ite1(3)
for i in i1:
    print(i) # 0到 5

第二种

class Ite2:
    
    def __init__(self, a, b):
        self.a = a
        self.b = b
        
    def __iter__(self):
        return self
    
    def __next__(self):
        self.a += 1
        if self.a > self.b+1: # 条件成立则迭代器结束
            raise StopIteration()
        return self.a-1
    
for i in Ite2(2,5):
    print(i) # 返回2-5

4、上下文管理

实现上下文管理,即可以和with结合使用

  • 要实现 __enter__ 和__exit__ 两个方法
  • __enter__会返回一个值,并赋值给as关键词之后的变量
  • __exit__ 定义了处理结束后要做的事情,比如文件的关闭,socket的断开等

5、索引取值

这里实现使用中括号索引取值,或者像字典一样操作

  • 实现 getitem方法
  • 这个方法的参数除了self,还可以指定一个index,之后return一个和index相关的结果,其实相当于把实例定义成了一个函数,但是是用中括号调用的
  • 结合 setitem delitem 即可让实例像字典一样操作
    只定义getitem
class Index1:

    def __getitem__(self, index):
        return 2 * index  # 如果定义和__next__中内容类似则实现既可以循环又可以[]取值了


i = Index1()
print(i[2])

#输出
4

全部定义

class Index2:
    
    def __init__(self,**kw):
        self.dict = kw 
            
    def __getitem__(self, key):
        return self.dict[key]
    
    def __setitem__(self, key, value):
        self.dict[key] = value
        
    def __delitem__(self, key):
        del self.dict[key]

i = Index2(name="Bob")
print(i['name'])  # 'Bob'
i['age'] = 13
print(i['age'])  # 13
del i['age']
print(i['age'])  #报错,删掉就没有这个属性了

相关文章

  • Python魔术方法

    Python魔术方法 Python 魔术方法指南 — PyCoder’s Weelky CNPython的魔术方法...

  • python魔术方法

    魔术方法:在python中,所有以“__”双下划线包起来的方法,都统称为“magic method”,例如最常用的...

  • 12.详解python常用到的魔术方法

    python中,用“__”双下划线包起来的方法,统称“魔术方法”;比如最常用的init,此方法定义一个对象的初始操...

  • Python面向对象的魔术方法

    魔术方法 查看类的魔术方法 输出结果如下 在Python中,所有以__双下划线包起来的方法,都统称为魔术方法。比如...

  • Python常用魔术方法总结

    __init__:构造函数 触发时机:实例化对象之后自动触发,在__new__之后执行。实例化对象其实包含两步,1...

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

    1.什么是魔术方法 在Python中以两个下划线开头和结尾的方法被称为魔术方法,魔术方法都是一些内置方法; 2.基...

  • Python中常用的魔术方法

    什么是魔术方法 python类中有一些方法前后都有两个下划线,这类函数统称为魔术方法。这些方法有特殊的用途,有的不...

  • 2017.6.13-14

    学习python总结python常用的方法string的常用方法dictionary的常用方法 python抽象,...

  • Python中给函数添加属性

    总所周知,Python里有一个非常出名的魔术方法是__str__,它常用于对于一个Python对象的字符转化,比如...

  • Python3 中的切片魔术方法

    从 Python3 的官方文档可知,Python3中的切片的魔术方法不再是Python2中的__getslice_...

网友评论

    本文标题:Python中常用的魔术方法

    本文链接:https://www.haomeiwen.com/subject/jooupktx.html