魔法方法

Posted zc110

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了魔法方法相关的知识,希望对你有一定的参考价值。

魔法方法

1.__init__类在实例化的时候会触发它的执行

2. __str__打印对象的时候会触发

class A:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return self.name


a = A(‘张三‘, 24)

print(a)

其实打印a 这个对象的时候,调用的就是 a.__str__这个方法,先找自己类里面有没有__str__这个方法,没有就到object去找,object里面的__str__一旦被调用,返回的就是这个方法的内存地址

3.__repr__

class A:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    # def __str__(self):
    #     return self.name

    def __repr__(self):
        return self.name

a = A(‘张三‘, 24)
print(a)
print(str(a))
print(repr(a))

__repr____str__的备胎,当你注释掉__str__,他就会启用__repr__,但是当你注释掉__repr__

print(repr(a))打印的是object里面repr 的内存地址

4.__call__


class A:
    def __init__(self,name):
        self.name =name 
    def __call__(self):
        for k in self.__dict__:
            print(k,self.__dict__[k])
a = A(‘aax‘)
a()
a = A(‘aax‘)()    

a()对象加一个括号就是调用__call__

5.item系列


class Foo:
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex


    def __getitem__(self, item):
        if hasattr(self,item):
            return self.__dict__[item]
    def __setitem__(self, key, value):
        self.__dict__[key] = value

    def __delitem__(self, key):
        del self.__dict__[key]
f = Foo(‘zz‘, ‘38‘, ‘男‘)
print(f[‘name‘])
f[‘hobby‘] = ‘base‘
print(f.hobby,f[‘hobby‘])
print(f.__dict__)
del f[‘hobby‘] # 自己实现的
def f.name # object 原生支持的 __delattr__
print(f.__dict__)

以前我们查找属性 只能f.name并不能像字典那样f[‘name‘],我们可以用item自定义我们自己的

6 __new__构造方法,创建一个对象


class A:
    def __init__(self):
        self.x = 1
        print(‘in init function‘)

    def __new__(cls, *args, **kwargs):
        print(‘in new function‘)
        return object.__new__(A, *args, **kwargs)


a = A()
print(a.x)


in new function
in init function
1

new创建self,在我们执行new的时候还没有self,所以new只能默认传类,这个时候__new__也没有self,借助object.new(A, *args, **kwargs)创建一个新的对象,return给__init__ self。 (__new__就是一个新的裸体的人,__init__就是穿了衣服的人)

7 __eq__

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

    def __eq__(self, other):
        if self.x + self.y == other.x + other.y:
            return True

        else:
            return False
a = A(1,2)
b = A(99,33)
print(a == b)
False

正常的情况是比较内存地址,我们重新定制这个eq方法会用我们定制的

8.__getattr____setattr__

class A:
    def __init__(self, name):
        self.name = name

    def __setattr__(self, key, value):

        if type(value) is str:
            self.__dict__[key] = value
        else:
            print(‘必须是字符串‘)

    def __getattr__(self, item):
        return self[item]

a = A(‘123‘)
a.name = 121
print(a.name)

__getattr____setattr__是 .拦截方法,不能用a[‘name‘] ,对象.属性会调用__setattr__,当我们赋值的时候如果不是字符串它返回的是信息是必须是字符串,当我们用a.name修改属性值的时候如果不是字符串,返回的也是必须是字符串,当我们打印的时候就是123

9 上下文管理

class A:

    def __enter__(self):
        print(‘我在管理的时候会触发‘)
        return ‘xx‘
    def __exit__(self, exc_type, exc_val, exc_tb):
        print(‘我用完了‘)
        print(‘1‘,exc_type)
        print(‘2‘,exc_val)
        print(‘3‘,exc_tb)


with A() as f:# 触发类__enter__
    print(f)
# 当管理完了,会触发__exit__


以上是关于魔法方法的主要内容,如果未能解决你的问题,请参考以下文章

Python类中的魔法方法

什么是method swizzling(俗称黑魔法)

Python中常见魔法方法介绍

VSCode自定义代码片段—— 数组的响应式方法

python学习--魔法方法

runtime:黑魔法之让人毫无知觉的修改类方法