Python10--类中的魔法方法

2021-03-30 12:25

阅读:641

标签:可调用对象   它的   __new__   pass   无效   通过   add   __init__   继承   

1.类中的特殊方法(魔法方法)
  • 在 Python 中有一些特殊的方法,它们是 Python 内置的方法,通常以双下划线来命名,比如__init____repr__ 等等,在类中使用它们时往往较少的代码就可以发挥很大的作用,提高开发效率,因此在 Python 中称这些方法为“魔法方法”
  • 在 Python 中最常使用的是__init__方法,它可以用于新建实例对象的时候给对象绑定属性,但是在新建对象的时候第一个调用的不是__init__方法,而是 __new__(cls, [...])方法,这两个方法的区别在于

1.__init__ 方法是在实例对象创建完成后调用的,主要用于设置实例对象的初始值,它的第一个参数为 self,可以不需要返回值
2. __new__ 方法是在实例对象被创建之前调用的,主要用于创建实例对象并返回实例对象,它的第一个参数为 cls ,它只会取 cls 参数,其余参数都传给了 __init__ 方法,必须要有返回值可以是 super().__new__(cls) 或是 object.__new__(cls)

# 作者:伊洛Yiluo 公众号:伊洛的小屋
# 个人主页:https://yiluotalk.com/
# 博客园:https://www.cnblogs.com/yiluotalk/
In [1]: class People:
   ...:     def __new__(cls, name):
   ...:         print(‘__new__‘)
   ...:         return super(People, cls).__new__(cls)
   ...:     def __init__(self, name):
   ...:         print(‘__init__‘)
   ...:         self.name = name
   ...:     def __del__(self):
   ...:         print(‘__del__‘)
   ...:

In [2]: man = People(‘Yiluo‘)
__new__
__init__

In [3]: man.name
Out[3]: ‘Yiluo‘

In [4]: del man
__del__

  • 由于 Python 是动态语言,因此定义一个实例对象后可以绑定任意的属性,如果需要限制绑定属性类别,可以使用 __slots__ 变量,可以绑定的属性值以元组的形式赋予给它。需要注意的是:__slots__的作用只在定义的类中有效,在继承该类的子类中是无效的。如果想要在子类中限制属性则需要重新定义,重新定以后,父类中的__slots__则会被子类继承
>>> class People:
...     __slots__ = (‘name‘, ‘age‘)
...
>>> somebody = People()
>>> somebody.name = ‘Yiluo‘
>>> somebody.age = 18
>>> somebody.name
‘Yiluo‘
>>> somebody.age
18
>>>
>>> class Man(People):
...     __slots__ = (‘city‘)
...
>>> person = Man()

>>> person.name = ‘Yiluo‘
>>> person.age = 18
>>> person.address = ‘shenzhen‘
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: ‘Man‘ object has no attribute ‘address‘
>>> person.city = ‘shenzhen‘
>>> person.name
‘Yiluo‘
>>> person.age
18
>>> person.city
‘shenzhen‘
2. __getattribute____getattr__
  • 在 Python 类中,当访问实例对象属性的时候,其实默认会调用__getattribute__方法,如果没有该属性就会报 AttributeError 错误,这个时候可以考虑使用 __getattr__ 方法进行自定义
3.__call__
  • 在 Python 中一切皆对象,对象分为可调用的和不可调用的,凡是可以通过一对括号 () 来调用的都是可调用对象,比如函数、类等,可以通过 callable() 函数来判断一个对象是否是可调用对象
>>> class People:
...     pass
...
>>> person = People()
>>> callable(person)
False
>>> callable(People())
False
>>> callable(People)
True
>>>
  • 通常情况下实例对象都是不可调用对象,但是如果在类中使用了 call 方法就可以将实例对象转换为可调用对象
>>> class People:
...     def __call__(self):
...         print(‘__call__‘)
...
>>> person = People()
>>> person()
__call__
>>> callable(person)
True
4.__iter__ __next__
  • 使用 __iter__方法就可以让类成为一个可迭代对象,如果使用 for 循环遍历类对象还需要在类中定义__next__ 方法,在__next__方法中可以定义取值的规则,当超出取值规则会抛出 StopIteration 异常从而退出当前循环
#!/usr/bin/env python3

class Test:
    def __init__(self, data=0):
        self.data = data
    def __iter__(self):
        return self
    def __next__(self):
        if self.data > 5:
            raise StopIteration
        else:
            self.data += 1
            return self.data

for i in Test():
    print(i)
  • 执行结果
?  code python3 demo.py
1
2
3
4
5
6

Python10--类中的魔法方法

标签:可调用对象   它的   __new__   pass   无效   通过   add   __init__   继承   

原文地址:https://www.cnblogs.com/yiluotalk/p/13582895.html


评论


亲,登录后才可以留言!