这篇文章主要介绍了python常用的魔法方法有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
python中一切皆对象,因为python是面向对象的编程语言。python给类和对象提供了大量的内置方法,这些内置方法也称魔法方法。这些魔法方法总是在某种条件下自动触发执行,就像魔法一样。
该方法是用来接收定义类时类中__new__方法返回的空对象后为空对象进行初始化的操作,没有返回值。
class Test(): def __init__(self, name): self.name = name def test(self): print(self.name) t = Test('xu') t1 = Test('python')
该方法是当类被调用实例化对象时首先被触发的方法,用来实例化一个空对象并返回。
class Test(): def __new__(cls,*args, **kwargs): return object.__new__(cls, *args, **kwargs) def __init__(self, name): self.name = name
如果想让一个对象变成一个可调用对象(加括号可以调用),需要在该对象的类中定义__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
当对象被访问打印时触发执行,该方法必须有一个字符串类型的返回值。
class Test(): def __init__(self, name): self.name = name def __str__(self): return self.name t = Test('xu') print(t1) # xu
__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__()
使用with上下文管理时,会触发对象中的__enter__方法,并将__enter__方法的返回值赋值给as声明的变量。
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系列方法包括__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系列方法包括__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
单例模式是一种软件设计模式,为了保证一个类无论调用多少次产生的对象都指向同一个内存地址,即仅仅只有一个对象。
实现单例模式的方式有很多,总的原则就是保证一个类只要实例化一个对象,因此关键点就是如何判断这个类是否实例化过一个对象。
这里介绍几种实现方式,供大家参考:
这种方式的原理是模块导入后只运行一次,后面再次使用该模块中的类是直接从内存中查找。
# 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
原理就是判断类是否有实力,有就直接返回,没有就保存到_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
感谢你能够认真阅读完这篇文章,希望小编分享的“python常用的魔法方法有哪些”这篇文章对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,更多相关知识等着你来学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。