1、什么是魔法方法?

  魔法方法就是可以给你的类增加魔力的特殊方法,如果你的对象实现(重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,你可以定义自己想要的行为,而这一切都是自动触发的。它们经常是两个下划线包围来命名的(比如 __init__,__lt__),Python的魔法方法是非常强大的,所以了解其使用方法也变得尤为重要!

2、__init__(self[, ...]),__new__(cls[, ...]),__del__(self)

  1)__init__ 构造器,当一个实例被创建的时候初始化的方法。但是它并不是实例化调用的第一个方法,__new__才是实例化对象调用的第一个方法,它只取下 cls 参数,并把其他参数传给 __init__。 __new__很少使用,但是也有它适合的场景,尤其是当类继承自一个像元组或者字符串这样不经常改变的类型的时候。

  2)__new__ 使用时注意以下四点:

    a) __new__  是在一个对象实例化的时候所调用的第一个方法;
    b)它的第一个参数是这个类,其他的参数是用来直接传递给 __init__ 方法;
    c) __new__  返回一个构建的实例;
    d) __new__  决定是否要使用该 __init__ 方法,因为 __new__ 可以调用其他类的构造方法或者直接返回别的实例对象来作为本类的实例,如果 __new__ 没有返回实例对象,则__init__ 不会被调用;
    e) __new__  主要是用于继承一个不可变的类型比如一个 tuple 或者 string。
 
 __new__实现单例模式(无论多少次实例化,结果都是同一个实例)

单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。

比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 AppConfig 对象的实例,这就导致系统中存在多个 AppConfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似 AppConfig 这样的类,我们希望在程序运行期间只存在一个实例对象。

举例:

class Person(object):
  def __init__(self, name, age):
    self.name = name
    self.age = age   def __new__(cls, *args, **kwargs):
    if not hasattr(cls,'instance'):
      cls.instance = super().__new__(cls)
    return cls.instance a = Person('p1',21)
b = Person('p2',22)
print(a == b, a.name == b.name)    # 这里的打印结果都是True,可见 a 和 b 都是同一个实例(实例 b 覆盖了实例 a)。

# 单例作用:
  #第一、控制资源的使用,通过线程同步来控制资源的并发访问;
  #第二、控制实例产生的数量,达到节约资源的目的;
  #第三、作为通信媒介使用,也就是数据共享。比如,数据库连接池的设计一般采用单例模式,数据库连接是一种数据库资源。 # 应用场景:
  #Python的logger就是一个单例模式,用以日志记录
  #线程池、数据库连接池等资源池一般也用单例模式
  #Windows的资源管理器是一个单例模式
  #网站计数器

  3)__del__ 析构器,当实例被销毁时调用。

3、__call__(self[,args ...]),__getitem__(self,key),__setitem__(self,key,value)

  1)__call__():允许一个类的实例本身可以像函数一样被调用,如下。

 class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
self.instance = add    # 实例对象加上(),将调用add()函数 def __call__(self,*args):
return self.instance(*args) def add(args):
return args[0] + args[1] a = Person('p1', 20)
print(a([1,2]))
#这里将打印 3
#可见当创建a这个对象之后,如果定义了__call__函数则对象是可以像函数一样调用的。

  2)__getitem__():定义获取容器中指定元素的行为,相当于字典的"[ ]"操作,如self[key]。示例如下。

 class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
self._registry = {
'name': name,
'age': age
} def __call__(self, *args):
return self.instance(*args) def __getitem__(self, key):
if key not in self._registry.keys():
raise Exception('Please registry the key:%s first !' % (key,))
return self._registry[key] a = Person('p1', 20)
print(a['name'],a['age'])
#这里打印的是 'p1' 20
#可见__getitem__使实例可以像字典一样访问

  3)__setitem__():设置容器中指定元素的行为,相当于字典的"[ ]"操作,如self[key] = value 。

4、__getattr__(self,name),__getattribute__(self,name),__setattr__(self,name,value),__delattr__(self,name)

  使用点"."操作时触发。

  1)__getattr__ ():当用户试图访问一个不存在属性时触发;

  2)__getattribute__(): 当一个属性(无论存在与否)被访问时触发;

  3)__setattr__ ():当一个属性被设置时触发;

  4)__delattr__ ():当一个属性被删除时触发。

 class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
self._registry = {
'name': name,
'age': age
} def __getattribute__(self, item):
#注意此处不要再访问属性,如self.__dict__[item]
#因为self.__dict__依然会被__getattribute__拦截,这样就会陷入死循环
return object.__getattribute__(self,item) def __getattr__(self, item):
print("don't have the attribute ",item)
return False def __setattr__(self, key, value):
self.__dict__[key] = value a = Person('p1', 20)
print(a.cs)   #这里会打印 don't have the attribute cs 以及 False
a.cs = '测试'  #这里设置该属性值为'测试'
print(a.cs) #这里将打印出'测试'

  

  至此,转载请注明出处。

Python 魔法方法简介的更多相关文章

  1. Python魔法方法总结及注意事项

    1.何为魔法方法: Python中,一定要区分开函数和方法的含义: 1.函数:类外部定义的,跟类没有直接关系的:形式: def func(*argv): 2.方法:class内部定义的函数(对象的方法 ...

  2. python魔法方法:__getattr__,__setattr__,__getattribute__

    python魔法方法:__getattr__,__setattr__,__getattribute__ 难得有时间看看书....静下心来好好的看了看Python..其实他真的没有自己最开始想的那么简单 ...

  3. python魔法方法大全

    1.python魔法方法详解: python魔法方法是可以修改重载的,如果你的对象实现(重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,你可以定义自己想要的行为,而 ...

  4. python 魔法方法补充(__setattr__,__getattr__,__getattribute__)

    python 魔法方法补充 1 getattribute (print(ob.name) -- obj.func())当访问对象的属性或者是方法的时候触发 class F(object): def _ ...

  5. 1. Python 魔法方法

    Python 魔法方法 基础: 如果你想... 所以,你写... Python调用... 初始化一个实例 x = MyClass() x.__init__() 作为一个字符串的"官方&quo ...

  6. with上下文管理 python魔法方法

    with语法在Python里很常见, 主要的利好是使用代码更简洁. 常见的使用场景有: 1. 资源对象的获取与释放. 使用with可以简化try...finally ... 2. 在不修改函数代码的前 ...

  7. python 魔法方法诠释

    什么是Python魔法方法 什么是魔法方法呢?它们在面向对象的Python的处处皆是.它们是一些可以让你对类添加"魔法"的特殊方法. 它们经常是两个下划线包围来命名的(比如 ini ...

  8. python 魔法方法

    I am not a creator, I just a porter. Note: Everything is object in python. 对于Python来说一切都是对象,也就是函数的参数 ...

  9. python 魔法方法之:__getitem__ __setitem__ __delitem__

    h2 { color: #fff; background-color: #7CCD7C; padding: 3px; margin: 10px 0px } h3 { color: #fff; back ...

随机推荐

  1. Struts1入门实例(简单登录)

    Struts1入门实例(简单登录) 现在开始加入公司的核心项目,但由于项目开发比较早,所以使用的技术不是很新潮,前台用的还是struts1. 虽然不是什么新技术,但仍可以从中学到好多东西的.花了一个晚 ...

  2. MFC控件编程之组合框跟列表框

    MFC控件编程之组合框跟列表框 一丶简介 如果要使用组合框跟列表框.那么就要知道.组合框列表框是最核心的东西就是索引. 索引是从0开始的. 二丶组合框列表框常用的方法 AddString(字符串) 添 ...

  3. 字符串不相同出现相同HashCode(算法)

    转自:https://blog.csdn.net/fly_grass_fish/article/details/81742794 在Java中有HashCode的说法,以前以为HashCode是唯一的 ...

  4. php-fpm无法使用系统环境变量的解决方法

    为了防止任意环境变量到达php-fpm进程,默认默认php-fpm是会清空系统环境变量的, 解决办法 修改php-fpm配置的clear_env = no (默认是yes)

  5. mcrypt加密以及解密过程

    Mcrypt库支持20多种加密算法和8种加密模式,具体可以通过函数mcrypt_list_algorithms()和mcrypt_list_modes()来显示 Mcrypt扩展库可以实现加密解密功能 ...

  6. 微软改名部又出动啦!微软宣布VSTS改名为Azure DevOps

    本篇为翻译,原文地址:https://azure.microsoft.com/en-us/blog/introducing-azure-devops/ 作者:Jamie Cool,Azure DevO ...

  7. Perl函数:字符串相关函数

    Perl字符串相关函数 字符串的内置函数有: chomp, chop, chr, crypt, fc, hex, index, lc, lcfirst, length, oct, ord, pack, ...

  8. Linux核心命令

    Linux核心命令 strace(查看系统调用的一个过程) 例:strace cat /test.txt netstat perf top pidstat mpstat dstat vmstat sl ...

  9. 南大算法设计与分析课程OJ答案代码(4)--变位词、三数之和

    问题 A: 变位词 时间限制: 2 Sec  内存限制: 10 MB提交: 322  解决: 59提交 状态 算法问答 题目描述 请大家在做oj题之前,仔细阅读关于抄袭的说明http://www.bi ...

  10. 【转载】Sqlserver强制密码过期导致数据库登录失败

    Sqlserver在设置登录账户信息的时候,有个复选框信息会被默认勾上,即强制实施密码策略,默认勾选上的还有强制密码过期.如果勾上了这个强制密码过期后,则你的账户密码在一定时间登录后会提示Sqlser ...