Магический метод Python | Магический метод двойного подчеркивания

задняя часть Python

«Эта статья участвовала в мероприятии Haowen Convocation Order, щелкните, чтобы просмотреть:Двойные заявки на внутреннюю и внешнюю стороны, призовой фонд в 20 000 юаней ждет вас, чтобы бросить вызов!"

Поиск общедоступных номеров Wechat [Программа Юань Сяочжуан], обратите внимание на то, как Чэн Юань, монах на полпути, полагается на разработку Python, чтобы поддерживать свою семью~

предисловие

В этой статье представлены магические методы, обычно используемые в Python, и очень важный шаблон singleton в объектно-ориентированном.

магический метод

Все в python является объектом, потому что python — это объектно-ориентированный язык программирования. Python предоставляет большое количество встроенных методов для классов и объектов, которые также называются магическими методами. Эти магические методы всегда срабатывают автоматически при определенных условиях, как и магия.

__init__метод

Этот метод используется для получения определенного класса в классе__new__После того, как метод возвращает пустой объект, инициализируется пустой объект, и возвращаемое значение отсутствует.

class Test():
    def __init__(self, name):
        self.name = name
        
    def test(self):
        print(self.name)
   
t = Test('xu')
t1 = Test('python')

__new__метод

Этот метод является первым методом, запускаемым при вызове класса для создания экземпляра объекта, создания экземпляра пустого объекта и возврата.

class Test():
    def __new__(cls,*args, **kwargs):
        return object.__new__(cls, *args, **kwargs) 
    
    def __init__(self, name):
        self.name = name

__call__метод

Если вы хотите, чтобы объект стал вызываемым объектом (вызываемым с помощью круглых скобок), вам необходимо определить его в классе объекта.__call__метод, возвращаемое значение вызова вызываемого объекта равно__call__Возвращаемое значение метода.

class Test():
    
    def __init__(self):
        self.name = 'python'
    
    def __call__(self, *args, **kwargs):  # self是Test类的对象
        print(self)  # <__main__.Test object at 0x000001C78CE78FD0>
        print(self.name)
        
t = Test()
t()  # python

__str___метод

Запускаемый при доступе к объекту и его печати, метод должен иметь возвращаемое значение строкового типа.

class Test():
    def __init__(self, name):
        self.name = name
	
    def __str__(self):
        return self.name
   
t = Test('xu')
print(t1)  # xu

__del___метод

__del__Метод автоматически срабатывает при удалении объекта.Поскольку механизм сборки мусора python будет автоматически очищать бесполезные ресурсы в программе, если объект занимает только ресурсы приложения, нет необходимости определять__del__метод, но если он предназначен для занятия системных ресурсов, таких как открытые файловые объекты, когда механизм сборки мусора python бесполезен из-за ресурсов операционной системы, для них необходимо создавать объекты__del__Метод используется для автоматического запуска восстановления ресурсов операционной системы после удаления объекта.

class Test:
    def __init__(self):
        self.x = open('a.txt',mode='w')
        # self.x = 占用的是操作系统资源

    def __del__(self):
        print('run')
        # 发起系统调用,告诉操作系统回收相关的系统资源
        self.x.close()

obj = T()
del obj # obj.__del__() 

__enter__ & __exit__метод

использоватьwithВо время управления контекстом это вызовет__enter__метод и воля__enter__Возвращаемое значение метода присваивается переменной, объявленной как.

Запускается, когда оператор with завершается нормально__exit__метод, три параметра этого метода представляют тип исключения, значение исключения и информацию о трассируемости соответственно.Если исключение возникает в блоке кода оператора with, код после оператора with не будет выполняться, но если возвращаемое значение методTrue, исключение будет очищено, а код после блока кода with будет выполняться в обычном режиме. код показывает, как показано ниже:

class Open:
    def __init__(self):
        self.name = 'open'

    def __enter__(self):
        print('with语句执行时会首先执行的方法,返回值会赋值给as声明的变量')
        return self.name

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('with中的代码块执行完毕时执行exit')
        print(exc_type, '如果出现异常表示异常类型')
        print(exc_val, '表示异常的值')
        print(exc_tb, '表示异常的溯源信息')
        return 123  # 非零 非空 非None为真

    
with Open() as test:
    print(test)
    raise TypeError('看一下错误信息')
print('我会不会被执行呢')  # 当__exit__方法返回值为真时,会被执行,否则不会被执行

itemметод серии

itemРяд методов включает__setitem__、__getitem__、delitem__метод, эти три метода будут запущены, когда квадратные скобки присваивают/изменяют значение, квадратная скобка принимает значение, а квадратная скобка удаляет значение.Например, вы можете настроить класс словаря и настроить метод квадрата присвоение скобок, получение значения и удаление значения. :

class MyDict(dict):

    def __setitem__(self, key, value):
        print('执行setitem', key, value)  # 执行setitem, x, 1
        self.__dict__[key] = value

    def __getitem__(self, item):
        print('执行getitem', item)  # 执行getitem x
        print(self.__dict__[item])  # 1

    def __delitem__(self, key):
        print('执行delitem', key)  # 执行delitem x
        self.__dict__.pop(key)


d = MyDict()
d['x'] = 1
print(d['x'])
del d['x']

attrметод серии

attrРяд методов включает__setattr__,__getattr__,__delattr__,__setattr__Срабатывает при добавлении/изменении свойств,___delattr__Запускается при удалении атрибута,__getattr__в настоящее время использует.Запускается, когда свойство вызывается, а свойство не существует. как показано в коде ниже

class Test:
    def __init__(self):
        self.name = 'python'

    def __setattr__(self, key, value):
        print('添加/修改属性setattr')
        self.__dict__[key] = value
        # self.key = value  # 会出现无线递归,因为对象.属性会调用__setattr__方法

    def __delattr__(self, item):
        print('删除属性delattr')
        self.__dict__.pop(item)

    def __getattr__(self, item):
        print('属性不存在时调用getattr')


t = Test()
t.x = 'x'
print(t.y)
del t.x

одноэлементный шаблон

Шаблон singleton — это шаблон разработки программного обеспечения, гарантирующий, что независимо от того, сколько раз вызывается класс, сгенерированные объекты указывают на один и тот же адрес памяти, то есть существует только один объект.

Существует множество способов реализации одноэлементного шаблона.Общий принцип заключается в том, чтобы убедиться, что классу нужно только создать экземпляр объекта, поэтому ключевым моментом является то, как определить, создал ли класс экземпляр объекта.

Вот несколько методов реализации для справки:

Как импортировать модули

Принцип этого метода заключается в том, что после импорта модуля он запускается только один раз, а классы в модуле снова используются непосредственно из памяти.

# cls_singleton.py
class Foo(object):
    pass

instance = Foo()

# test.py
import cls_singleton

obj1 = cls_singleton.instance
obj2 = cls_singleton.instance
print(obj1 is obj2)  # True

пройти через__new__метод

Принцип состоит в том, чтобы определить, есть ли у класса сила, вернуться сразу же, если она есть, и сохранить ее для_instanceсередина

class Test:

    _instance = None

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

    def __new__(cls, *args, **kwargs):
        # if cls._instance:
        #     return cls._instance	                # 有实例则直接返回
        # else:
        #     cls._instance = super().__new__(cls)	# 没有实例则new一个并保存
        #     return cls._instance	                # 这个返回是给是给init,再实例化一次,也没有关系

        if not cls._instance:	                        # 这是简化的写法,上面注释的写法更容易提现判断思路
            cls._instance = super().__new__(cls)
        return cls._instance


t1 = Test('python', 18)
t2 = Test('python1', 18)
print(t1 is t2)  # True

Способы настройки метаклассов

Принцип этого метода заключается в процессе вызова класса. Когда класс определен, он вызывает подкласс под метаклассом.__init__, когда вызывается класс (экземпляр объекта), он срабатывает в метаклассе__call__метод.

class Mymeta(type):

    def __init__(cls, name, bases, dic):
        super().__init__(name, bases, dic)
        cls._instance = None		                  # 将记录类的实例对象的数据属性放在元类中自动定义了

    def __call__(cls, *args, **kwargs):	                  # 此call会在类被调用(即实例化时触发)
        if cls._instance:				  # 判断类有没有实例化对象
            return cls._instance
        else:						  # 没有实例化对象时,控制类造空对象并初始化
            obj = cls.__new__(cls, *args, **kwargs)
            obj.__init__(*args, **kwargs)
            cls._instance = obj			          # 保存对象,下一次再实例化可以直接返回而不用再造对象
            return obj


class Test(metaclass=Mymeta):
    def __init__(self, name, age):
        self.name = name
        self.age = age


t1 = Test('python', 18)
t2 = Test('python1', 18)
print(t1 is t2)  # True

Эпилог

Статья была впервые опубликована в публичном аккаунте WeChat.程序媛小庄, синхронизировано сНаггетс,Знай почти.

Кодировать слова непросто, объясните, пожалуйста, источник перепечатки, а маленькие друзья, которые проходят мимо, протягивают свои милые пальчики и ставят лайк перед уходом (╹▽╹)

wallhaven-z8ykry.jpg