[Python] 定制类:基础篇

4.10 定制类(魔法方法、魔术方法、专有方法)

在Python中,定制类是一种通过定义特定的方法来定制类的行为和属性的方式。Python提供了许多预定义的特殊方法(也称为魔术方法或双下划线方法),这些方法可以被自定义类覆盖以实现不同的功能。
一般魔法方法名都是以__开头和结尾。在前面的教程或者日常学习使用中,我们都已经或多或少的接触过一些魔法方法了,比如:__init__等。

4.10.1 基础篇

4.10.1.1 newinit

这2个魔法方法可以让你改变从一个类建立一个对象时候的行为。这2个魔法方法也比较容易搞混。
这个__new__是从一个class建立一个object的过程。
而__init_是有了这个object之后,给这个object初始化的过程。

class A:
    def __new__(cls, *args, **kwargs):
        print('__new__', args, kwargs)
        return super().__new__(cls)

    def __init__(self, *args, **kwargs):
        print('__init__', args, kwargs)


a = A(1)

new (1,) {}
init (1,) {}

在类的初始化时,传入的参数会同时传给__new__、init,并且__new__方法是必须要有返回值的,返回的就是该对象本身。而__init__则不需要返回。上面的类的初始化相当于:
obj = new(A, 1)
a = init(obj, 1)
__new__方法一般很少会用到,只有在元类、单例模式时才会用到。而__init__方法则经常会用到。一般在__init__方法里,我们需要处理一些类在实例化成对象时,要初始化的操作。

4.10.1.2 del

__del__方法可以粗略的理解为一个析构函数。当对象被释放的时候,就会调用这个方法,这个时候我们就可以在该方法内写上要具体的措施。

from icecream import ic


class A:
    def __del__(self):
        print('__del__')


a = A()
ic()
ic(a)

16:31:34|> t1.py:10 in at 16:31:34.128
16:31:34|> a: <main.A object at 0x000001CEFDB0B310>
del

注意:
1、在Python中,Python自动释放对象比较不可控,所以这个__del__方法不是那么的好用。
2、del关键字和这个__del__并无关系,用del obj时并不一定会触发该对象的__del__方法。del obj只是让这个obj少一个引用。

4.10.1.3 reprstr

这两个魔法方法的功能是相似的。都是返回这个obj的字符串表示。这2个方法之间主要是语义上的不同。
一般来说,__str__这个函数返回的内容是人类更容易理解的string,比较注重可读性。
而__repr__返回的内容一般有更详细的信息。
在某个类中,如果这2个方法都定义了,那么print会使用__str__函数返回的内容。可以使用repr、str分别直接调用obj中的__repr__和__str__方法。并得到返回的结果:

class A:
    def __repr__(self):
        return 'repr'

    def __str__(self):
        return 'str'


a = A()
print(a)
print(repr(a))
print(str(a))

str
repr
str

如果没有定义__str__,那么repr、str返回的都是__repr__方法结果。

4.10.1.4 format

当我们尝试用某种格式打印对象时,就有可能调用到这个__format__方法。

from icecream import ic


class A:
    def __format__(self, format_spec):
        if format_spec == 'x':
            return '0xA'
        return 'A'


ic(f'{A()}')
ic(f'{A():x}')
ic('{}'.format(15))
ic('{:b}'.format(15))
ic('{:x}'.format(15))
ic(f'{15}')
ic(f'{15:b}')
ic(f'{15:x}')

15:15:29|> f’{A()}‘: ‘A’
15:15:29|> f’{A():x}‘: ‘0xA’
15:15:29|> ‘{}’.format(15): ‘15’
15:15:29|> ‘{:b}’.format(15): ‘1111’
15:15:29|> ‘{:x}’.format(15): ‘f’
15:15:29|> f’{15}‘: ‘15’
15:15:29|> f’{15:b}‘: ‘1111’
15:15:29|> f’{15:x}': ‘f’

4.10.1.5 bytes

当你尝试用你自己的这个class去建立一个bytes的时候,应该返回什么。一般很少会用到。除非要定制化class的bytes的返回。

from icecream import ic


class A:
    def __bytes__(self):
        print('__bytes__')
        return bytes([0, 1])


ic(bytes(A()))

bytes
15:17:57|> bytes(A()): b’\x00\x01’

你可能感兴趣的:(Python进阶,#,四,类的进阶知识,python,开发语言)