一 __new__ 魔术方法

1.1 介绍

  • 触发时机:实例化类生成对象的时候触发(触发时机在__init__之前)
  • 功能:控制对象的创建过程
  • 参数:至少一个cls接受当前的类,其他根据情况决定
  • 返回值:通常返回对象或None
对象.属性
对象.方法() 类.属性
类.方法()

1.2 基本用法

class MyClass():
abc = 123
def __new__(cls): #把class这个类传递__new__这个方法
print (123)
return None #返回一个None #实例化对象
obj = MyClass()
print (obj)

执行

这样就不能使用使用obj这个对象调用abc的值

class MyClass():
abc = 123
def __new__(cls):
print (123)
return None #实例化对象
obj = MyClass()
print (obj)
print (obj.abc) #在这里就相当于使用None.abc.这种此写法不允许,就会报错

执行

借助父类创建对象

返回本类对象

class MyClass():
abc = 123
def __new__(cls):
          print (cls)
print (123)
#要借助父类object的__new__创建对象
obj = object.__new__(cls)
return obj #实例化对象
obj = MyClass()
print (obj)
print (obj.abc)

执行

[root@node10 python]# python3 test.py
<class '__main__.MyClass'> #cls是一个类
123
<__main__.MyClass object at 0x7ff2808ba3c8>
123
[root

返回空对象

class MyClass():
abc = 123
def __new__(cls):
print (cls)
print (123)
#要借助父类object的__new__创建对象
obj = object.__new__(cls)
#return obj
return None #实例化对象
obj = MyClass()
print (obj)
print (obj.abc)

执行

返回一个其他类的对象

class MyClass2():
ccc = 4
obj2 = MyClass2()
class MyClass():
abc = 123
def __new__(cls):
print (cls)
print (123)
#要借助父类object的__new__创建对象
obj = object.__new__(cls)
#return obj
#return None
return obj2 #实例化对象
obj = MyClass()
print (obj)
print (obj.abc)

执行

修改属性

[root@node10 python]# cat test.py
class MyClass2():
ccc = 4
obj2 = MyClass2()
class MyClass():
abc = 123
def __new__(cls):
print (cls)
print (123)
#要借助父类object的__new__创建对象
obj = object.__new__(cls)
#return obj
#return None
return obj2 #实例化对象
obj = MyClass()
print (obj)
print (obj.ccc)

执行

[root@node10 python]# python3 test.py
<class '__main__.MyClass'>
123
<__main__.MyClass2 object at 0x7fb463cc7470>
4

1.3 对__new__和__init__这两个魔术方法的区别

调用的顺序

class Boat():
def __new__(cls):
print (1)
return object.__new__(cls)
def __init__(self):
print (2)
obj = Boat()
print (obj)

执行

[root@node10 python]# python3 test.py
1
2
<__main__.Boat object at 0x7f9bb5fcf400>

先调用__new__在调用__init__

调用和定义的顺序无关

class Boat():
def __init__(self):
print (2)
def __new__(cls):
print (1)
return object.__new__(cls)
obj = Boat()
print (obj)

执行

[root@node10 python]# python3 test.py
1
2
<__main__.Boat object at 0x7f95a73cf400>

结果一样

__new__ 的触发时机要快于 __init__
__new__ 是用来创建对象的
__init__ 是用来初始化对象的 先得有对象
才能初始化对象 new 和 init 他门的参数要保持一致.

1.4  如果返回的不是一个本类对象__init__就不会触发

class Boat():
def __new__(cls):
print (1)
#return object.__new__(cls)
return None
def __init__(self):
print (2)
obj = Boat()
print (obj)

执行

[root@node10 python]# python3 test.py
1
None

初始化参数

class Boat():
def __new__(cls):
print (1)
return object.__new__(cls)
#return None
def __init__(self,name):
self.name = name
obj = Boat("John")
print (obj.name)

执行

[root@node10 python]# python3 test.py
Traceback (most recent call last):
File "test.py", line 8, in <module>
obj = Boat("John")
TypeError: __new__() takes 1 positional argument but 2 were given

这是因为,__new__先于__init__调用,但是,在调用的时候,已经传递了一个类(cls)的参数,name的参数就不能对应报错

class Boat():
def __new__(cls,name):
print (1)
return object.__new__(cls)
#return None
def __init__(self,name):
self.name = name
obj = Boat("John")
print (obj.name)

执行,而可以调用

[root@node10 python]# python3 test.py
1
John

1.5 使用参数的普通参数和关键字实参

lass Boat():
def __new__(cls,*args,**kwargs):
print (1)
return object.__new__(cls)
#return None
def __init__(self,*args,**kwargs):
strvar = ""
for i in args:
strvar += i + " "
print (strvar)
print (kwargs)
obj = Boat("John","Jim","Tom",name="David")

执行

[root@node10 python]# python3 test.py
1
John Jim Tom
{'name': 'David'}

1.6 如果__new__魔术方法返回的时其他类的对象,不会触发__init__ 本类的魔术方法

class MyClass2():
ccc = 4
obj2 = MyClass2()
class Boat():
def __new__(cls,*args,**kwargs):
print (1)
#return object.__new__(cls)
return obj2
def __init__(self,*args,**kwargs):
print (111)
obj = Boat("John","Jim","Tom",name="David")
print (obj.ccc)

执行

[root@node10 python]# python3 test.py
1
4

二 单态模式

无论实例化类几次,都有且只有一个对象.为了节省内存空间

2.1 创建一个类,实例化三个对象

[root@node10 python]# cat test.py
class Singleton():
pass
obj1 = Singleton()
print (obj1)
obj2 = Singleton()
print (obj2)
obj3 = Singleton()
print (obj3)

执行

[root@node10 python]# python3 test.py
<__main__.Singleton object at 0x7efd7ec76400>
<__main__.Singleton object at 0x7efd7ec76438>
<__main__.Singleton object at 0x7efd7ec76470>

可以看到占用不同的内存空间

2.2 使用单态模式

class Singleton():
#创建一个私有的对象,类外无法调用
__obj = None
#定义一个方法
def __new__(cls):
#判断这个对象是否为None对象
if cls.__obj is None:
obj = object.__new__(cls) #如果是,就重新创建一个新的对象
cls.__obj = obj #把这新的对象夫给类的私有方法
return cls.__obj #如果不是None,直接返回
obj1 = Singleton()
print (obj1)
obj2 = Singleton()
print (obj2)
obj3 = Singleton()
print (obj3)

执行

[root@node10 python]# python3 test.py
<__main__.Singleton object at 0x7fbae7edb4a8>
<__main__.Singleton object at 0x7fbae7edb4a8>
<__main__.Singleton object at 0x7fbae7edb4a8>

发现三个对象都是一个内存地址

2.3 实际的含义,对象和init之间的关系

class Singleton():
#创建一个私有的对象,类外无法调用
__obj = None
#定义一个方法
def __new__(cls,name):
#判断这个对象是否为None对象
if cls.__obj is None:
cls.__obj = object.__new__(cls)
return cls.__obj
def __init__(self,name):
self.name = name
obj1 = Singleton("John")
obj2 = Singleton("Frnak")
print (obj1.name)
print (obj2.name)

执行

[root@node10 python]# python3 test.py
Frnak
Frnak

032.Python魔术方法__new__和单态模式的更多相关文章

  1. day24:多态&魔术方法__new__&单态模式

    目录 1.多态 2.__new__魔术方法 2.1 关于魔术方法__new__ 2.2 基本语法 2.3 __new__ 触发时机快于构造方法 2.4 __new__ 和 __init__ 参数一一对 ...

  2. python魔术方法

    在类中有一些特殊的方法具有特殊的意义,比如__init__和__del__方法,它们的重要性我们已经学习过了. 一般说来,特殊的方法都被用来模仿某个行为.例如,如果你想要为你的类使用x[key]这样的 ...

  3. Python 魔术方法笔记

    魔术方法总是被__包围, 如__init__ , __len__都是常见的魔术方法,这里主要写一下我遇到的一些魔术方法 setitem 对某个索引值赋值时 即可以进行赋值操作,如 def __seti ...

  4. 记一次 Apache HUE 优化之因使用 Python 魔术方法而遇到的坑

    最近的工作是基于 Apache HUE 做二次开发.刚接手 HUE 的代码的时候,内心是崩溃的:开源的代码,风格很多种, 代码比较杂乱; 虽是基于 Django 开发的,但是项目的结构改变很大; 很多 ...

  5. Python的程序结构[1] -> 方法/Method[3] -> 魔术方法 __getattr__ 与代理模式

    __getattr__ 方法 __getattr__ 方法当对象调用内部属性(包括方法等)且未找到对应属性的时候会调用的特殊方法.利用这一特性,可是对函数实现一个代理模式. __getattr__方法 ...

  6. Python魔术方法-Magic Method

    介绍 在Python中,所有以"__"双下划线包起来的方法,都统称为"Magic Method",例如类的初始化方法 __init__ ,Python中所有的魔 ...

  7. Python 魔术方法指南

    入门 构造和初始化 构造定制类 用于比较的魔术方法 用于数值处理的魔术方法 表现你的类 控制属性访问 创建定制序列 反射 可以调用的对象 会话管理器 创建描述器对象 持久化对象 总结 附录 介绍 此教 ...

  8. [python]魔术方法

    一.初始化: 1.__new__方法,初始化过程中第一个用到的方法(用处不大). 2.之后,__init__方法,构造方法. 3.最后,在对象回收时,调用__del__方法.如果解释器退出时,对象还存 ...

  9. Python 魔术方法及调用方式

    魔术方法 调用方式 解释 __new__(cls [,...]) instance = MyClass(arg1, arg2) __new__ 在创建实例的时候被调用 __init__(self [, ...

随机推荐

  1. odoo视图入门学习- tree视图的使用

    上一篇内容:如何快速在odoo中创建自己的菜单 前言 上面的内容我们已经学会了如何去创建odoo的菜单,下面我们要学习的是odoo的基础视图tree视图,我们的目标是实现型号管理的列表页面 创建mod ...

  2. spieces-in-pieces动画编辑器

    前言: 制作灵感来源于 http://species-in-pieces.com/ 这个网站,此网站作者是来自阿姆斯特丹的设计师 Bryan James,其借用纯CSS技术表现出30种濒危动物的碎片拼 ...

  3. 序列化 pickle模块

    1. pickle 简介 2. pickle 核心函数 3. pickle 高级 -- 复杂对象 1. 持久化与 pickle 简介 1.1 什么是持久化? 持久化的基本思想很简单.假定有一个 Pyt ...

  4. 记canvas画笔笔迹的多次优化过程

    我们的项目是面向学校老师的教学软件,所以肯定少不了互动白板的功能,而这个里面的画笔功能是由我来开发的,下面介绍这个过程中遇到的问题以及解决方法. 首先给大家明确下由于软件中的画布可以自由移动,会超出屏 ...

  5. @unittest.skip(reason):强制跳转。reason是跳转原因

    在执行测试用例时,有时候有些用例是不需要执行的,那我们怎么办呢?难道删除这些用例?那下次执行时如果又需要执行这些用例时,又把它补回来?这样操作就太麻烦了. unittest提供了一些跳过指定用例的方法 ...

  6. 软件篇-06-SLAM小车Self Navigation

    当SLAM小车能够以较高的精度运动到人为设置的目标点时,下一步就是把SLAM小车放到一个陌生的环境中,让它自己建图了.为什么?因为它已经是一只成熟的SLAM小车了.   我这里写的比较简单,刚写还没几 ...

  7. hdu3035 最小割转换成最短路

    题意:       给你一个平面图,要求从求出从左上角到右下角的最小割. 思路:       如果大意的可能直接上来一遍最大流,然后就会各种悲剧的MLE,TLE,其实这个题目可以用到有个论文里面的那个 ...

  8. 010 Editor体验

    源代码的我们现在拥有各式各样的IDE和编辑器可以去查看,但二进制文件对于大多数软件只能做到显示16进制,而不能按照文件类型的格式去显示.今天我们就用dex文件让010 show. 安装软件: http ...

  9. 手脱UPX3.91壳(练习)

    0x01 准备 OD UPX加壳程序 可以加壳的软件 0x02 给软件加壳 我找了半天发现winhex不错,而且是没壳的可以直接加壳 1.复制一份可执行文件 将赋值好的文件用UPX3.91加壳 0x0 ...

  10. 内核模式下的线程同步的分析(Windows核心编程)

    内核模式下的线程同步 内核模式下的线程同步是用户模式下的线程同步的扩展,因为用户模式下的线程同步有一定的局限性.但用户模式下线程同步的好处是速度快,不需要切换到内核模式(需要额外的 CPU 时间).通 ...