类的内置方法(魔法方法):

  凡是在类内部定义,以__开头__结尾的方法,都是类的内置方法,也称之为魔法方法。

  类的内置方法,会在某种条件满足下自动触发。

内置方法如下:
  __new__: 在__init__触发前,自动触发。 调用该类时,内部会通过__new__产生一个新的对象。
  __init__: 在调用类时自动触发。 通过产生的对象自动调用__init__()

class Demo(object):
# 条件: __new__: 在__init__触发前,自动触发。
def __new__(cls, *args, **kwargs):
print('此处是__new__方法的执行')
# python内部通过object调用内部的__new__实现产生一个空的对象 ---> 内存地址
return object.__new__(cls,*args,**kwargs) # 条件: __init__: 在调用类时自动触发。
def __init__(self):
print('此处是__init__方法的执行') demo_obj=Demo()
'''result:
此处是__new__方法的执行
此处是__init__方法的执行
'''

__getattr__: 在 “对象.属性” 获取属性时,若 “属性没有” 时触发。

class Demo(object):
# __getattr__: 在 “对象.属性” 获取属性时,若 “属性没有” 时触发。
def __getattr__(self, item):
print('此处是__getattr__方法的执行')
print(item)
     # return 想要返回的值
return '别闹,没有该属性' demo_obj=Demo()
print(demo_obj.x)
'''
此处是__getattr__方法的执行
x
别闹,没有该属性
'''
demo_obj.x=3
print(demo_obj.x) #
条件: __getattribute__: 在 “对象.属性” 获取属性时,无论 "属性有没有" 都会触发。
注意: 只要__getattr__ 与 __getattribute__ 同时存在类的内部,只会触发__getattribute__。
class Demo(object):
# 条件: __getattribute__: 在 “对象.属性” 获取属性时,无论 "属性有没有" 都会触发。
def __getattribute__(self, item):
print('此处是__getattribute__方法的执行')
print(item,'<-----打印属性名字')
# return self.__dict__[item] # 注意: 此处不能通过 对象.属性,否则会产生递归调用,程序崩溃
# return getattr(self.item) # getattr: 内部调用了 ----> __getattribute__, 也会递归 # 注意: 只要__getattr__ 与 __getattribute__ 同时存在类的内部,只会触发__getattribute__。
demo_obj=Demo()
print(demo_obj.x)
'''
此处是__getattribute__方法的执行
x <-----打印属性名字
None
'''
demo_obj.x=3
print(demo_obj.x) #
'''
此处是__getattribute__方法的执行
x <-----打印属性名字
None
'''

条件: 当 “对象.属性 = 属性值” , 添加或修改属性时触发

class Demo(object):
# 条件: 当 “对象.属性 = 属性值” , 添加或修改属性时触发
def __setattr__(self, key, value): # key---> 对象.属性名 value ---》 属性值
print('# key---> 对象.属性名 value ---》 属性值')
print(key,value)
#self.key=value #产生递归 self.__dict__[key]=value # 此处是对 对象的名称空间 ---》 字典进行操作 demo_obj=Demo()
# print(demo_obj.x) demo_obj.x=3
'''
# key---> 对象.属性名 value ---》 属性值
x 3
'''
print(demo_obj.x) #

条件: 在调用对象 “对象 + ()” 时触发。

class Demo(object):
# 条件: 在调用对象 “对象 + ()” 时触发。
def __call__(self, *args, **kwargs):
print('此处是__call__方法的执行')
#调用对象时返回的值
return [1,2,3,4,5] demo_obj=Demo()
res=demo_obj() # 此处是__call__方法的执行
print(res) # [1, 2, 3, 4, 5]

条件: 在打印对象时触发。

class Demo:
# 条件: 在打印对象时触发。
#注意:该方法必须要有一个"字符串"返回值
def __str__(self):
print('此处是__str__方法的执行')
return '' demo_obj=Demo()
print(demo_obj)
'''
此处是__str__方法的执行
111
'''

在对象通过 “对象[key]” 获取属性时触发。

class Demo:
# 在对象通过 “对象[key]” 获取属性时触发。
def __getitem__(self, item):
print('此处是__getitem__方法的执行')
print(item)
return self.__dict__[item] demo_obj=Demo()
demo_obj.x=10
res=demo_obj['x']
'''
此处是__getitem__方法的执行
x
'''
print(res) #

在对象通过 “对象[key]=value值” 设置属性时触发。

class Demo:
# 在对象通过 “对象[key]=value值” 设置属性时触发。
def __setitem__(self, key, value):
print('此处是__setitem__方法的执行')
print(key,value)
self.__dict__[key] = value demo_obj=Demo()
demo_obj['y']=300
'''
此处是__setitem__方法的执行
y 300
'''
print(demo_obj.y) #

单例模式:

  指的是在确定 "类中的属性与方法" 不变时,需要反复调用该类,
  产生不同的对象,会产生不同的内存地址,造成资源的浪费。

  让所有类在实例化时,指向同一个内存地址,称之为单例模式。 ----> 无论产生多个对象,都会指向 单个 实例。

  - 单例的优点:
    节省内存空间。

#反面案例
class Foo:
def __init__(self,x,y):
self.x=x
self.y=y foo_obj1=Foo(10,20)
print(foo_obj1) # <__main__.Foo object at 0x0000000001D85CF8>
foo_obj2=Foo(10,20)
print(foo_obj2) # <__main__.Foo object at 0x00000000021BCC88>

单例模式: (面试让你手撸,一定要背下来。)
1.通过classmethod
2.通过装饰器实现
3.通过__new__实现
4.通过导入模块时实现
5.通过元类实现。

classmethod实现

class MySQL:
# 一个默认值,用于判断对象是否存在, 对象不存在证明值是None
# __instance是类的属性,可以由类来调用
__instance = None # ---》 若已有对象会返回给它 ---》 obj
# __instance = obj def __init__(self,host,port):
self.host=host
self.port=port @classmethod
def singleton(cls,host,port): # 单例方法 ---》 类方法 # 判断__instance中若没有值,证明没有对象
if not cls.__instance:
# 产生一个对象并返回
obj=cls(host,port)
# None ---> obj
cls.__instance=obj # 若__instance中有值,证明对象已经存在,则直接返回该对象
return cls.__instance
def start_mysql(self):
print('启动mysql')
def close(self):
print('关闭mysql')
obj1=MySQL.singleton('180.101.49.12',443)
print(obj1) # <__main__.MySQL object at 0x000000000255D160>
obj2=MySQL.singleton('180.101.49.12',443)
print(obj2) # <__main__.MySQL object at 0x000000000255D160>

或者:

class Borg:
def __new__(cls, *args, **kwargs):
if not hasattr(cls,'_instance'):
ob = super(Borg,cls)
cls._instance = ob.__new__(cls,*args,**kwargs)
return cls._instance # if not hasattr(cls,'_instance'):
# # 造一个空对象
# cls._instance = object.__new__(cls)
# return cls._instance class MyClass(Borg):
def __init__(self):
self.a = 1 obj1 = MyClass()
obj2 = MyClass()
print(obj1)
print(obj2)

__new__实现

# __new__创造单例模式
class Singleton:
__instance = None
@classmethod # 此处可以不加此装饰器,__new__默认为类方法
def __new__(cls, *args, **kwargs):
if not cls.__instance:
# 造一个空对象
cls.__instance = object.__new__(cls)
return cls.__instance obj1= Singleton()
obj2= Singleton()
obj3= Singleton()
print(obj1) # <__main__.Singleton object at 0x000000000255D048>
print(obj2) # <__main__.Singleton object at 0x000000000255D048>
print(obj3) # <__main__.Singleton object at 0x000000000255D048>

装饰器实现

def singleton(cls):
_instance = {} #此处必须为可变类型
def inner(*args,**kwargs):
if cls not in _instance:
_instance[cls] = cls(*args,**kwargs)
return _instance[cls]
return inner @singleton
class Father:
pass print(Father()) # <__main__.Father object at 0x0000000001DA5D68>
print(Father()) # <__main__.Father object at 0x0000000001DA5D68>

为什么不能用_instance=None赋值说明

def singleton(cls):
_instance = None #此处必须为可变类型
def inner(*args,**kwargs):
if not _instance: # 报错,因为_instance优先指向内置空间的对象,也就是下面的_instance,没有就报错,无解!此处必须用字典等方法
_instance = cls(*args,**kwargs)
return _instance
return inner @singleton
class Father:
pass print(Father())
print(Father())

模块导入

# 以下为singleton模块
class SingletonCls:
pass
obj = SingletonCls() # 以下为测试程序
from singleton模块 import obj
print(obj)
print(obj)

python基础语法18 类的内置方法(魔法方法),单例模式的更多相关文章

  1. python基础(14)-反射&类的内置函数

    反射 几个反射相关的函数可参考python基础(10)-匿名函数&内置函数中2.2.4反射相关 类的一些内置函数 __str__()&__repr__() 重写__str__()函数类 ...

  2. Python基础(协程函数、内置函数、递归、模块和包)-day05

    写在前面 上课第五天,打卡: 凭着爱,再回首: 一.协程函数(生成器:yield的表达式形式) 1.yield 的语句形式: yield 1 - 这种方式在 Python基础(函数部分)-day04  ...

  3. python面向对象的多态-类相关内置函数-类内置魔法函数-迭代器协议-上下文管理-04

    多态 一种事物具备不同的形态 例如:水 --> 固态.液态.气态 多态:# 多个不同对象可以相应同一个对象,产生不同的结果 首先强调,多态不是一种特殊的语法,而是一种状态,特性(多个不同对象可以 ...

  4. python基础7之python3的内置函数

    官方介绍: python3:https://docs.python.org/3/library/functions.html?highlight=built#ascii python2:https:/ ...

  5. Python基础(10)_内置函数、匿名函数、递归

    一.内置函数 1.数学运算类 abs:求数值的绝对值 divmod:返回两个数值的商和余数,可用于计算页面数 >>> divmod(5,2) (2, 1) max:返回可迭代对象中的 ...

  6. JS基础-语法+流程控制语句+函数+内置对象【数组】

    JS语法: Javascript基本数据类型:undefined/null/Boolean/number/string 复杂数据类型:object typeof用来检测变量的数据类型 typeof的使 ...

  7. python - setitem/getitem/delitem类的内置方法

    # class 内置方法: # __setitem__ # __getitem__ # __delitem__ class Test(): X = 100 def __getitem__(self, ...

  8. python基础操作以及其常用内置方法

    #可变类型: 值变了,但是id没有变,证明没有生成新的值而是在改变原值,原值是可变类型#不可变类型:值变了,id也跟着变,证明是生成了新的值而不是在改变原值,原值是不可变 # x=10# print( ...

  9. Python之面向对象:类的内置方法

    1.def __add__(self,other): c1+c2 两个实例的加法操作就是执行__add__()方法 2.__str__(self): print一个实例的时候,执行的是__str__( ...

随机推荐

  1. [LeetCode] 350. Intersection of Two Arrays II 两个数组相交之二

    Given two arrays, write a function to compute their intersection. Example 1: Input: nums1 = [1,2,2,1 ...

  2. 本地搭建WordPress (XAMPP环境)

    1,XAMPP是一个流行的PHP开发环境,官网下载: https://www.apachefriends.org/zh_cn/index.html 然后安装. 官方介绍:XAMPP是最流行的PHP开发 ...

  3. PDMan-2.1.0 正式发布:用心开源,免费的国产数据库建模工具 PowerDesigner

    PDMan是一款开源免费的数据库模型建模工具,支持Windows,Mac,Linux等操作系统,是PowerDesigner之外,更好的免费的替代方案.他具有颜值高,使用简单的特点.包含数据库建模,灵 ...

  4. 【转】ubuntu16.04安装Vivado 2017.4 教程

    ubuntu16.04安装Vivado 2017.4 教程 2017-12-28 20:59:48 wmyan 阅读数 11794   版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协 ...

  5. Ubuntu 16 PPA源管理(查询、添加、修改、删除)

    查询 在Ubuntu中,每个PPA源是单独存放在/etc/apt/sources.list.d/文件夹中的,进入到该文件夹,使用ls命令查询即可列出当前系统添加的PPA源. 添加 sudo add-a ...

  6. 【BZOJ4016】[FJOI2014]最短路径树问题(点分治,最短路)

    [BZOJ4016][FJOI2014]最短路径树问题(点分治,最短路) 题面 BZOJ 洛谷 题解 首先把最短路径树给构建出来,然后直接点分治就行了. 这个东西似乎也可以长链剖分,然而没有必要. # ...

  7. 【模板整合计划】NB数论

    [模板整合计划]NB数论 一:[质数] 1.[暴力判] 素数.コンテスト.素数 \(\text{[AT807]}\) #include<cstdio> #include<cmath& ...

  8. 图解微信小程序---轮播图

    图解微信小程序---轮播图 代码笔记 第一步:在页面创建swiper组件 第二步:编写js页面 注意事项:wx:for渲染我们js中的图片数组,item默认写法,获取我们的图片数组中的图片,可通过增加 ...

  9. mosquitto 常用命令

    原文:https://www.cnblogs.com/smartlife/articles/10182136.html 常用命令 订阅主题 mosquitto_sub -h 192.168.0.1 - ...

  10. C#多线程下如何保证线程安全?

    多线程编程相对于单线程会出现一个特有的问题,就是线程安全的问题.所谓的线程安全,就是如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码.如果每次运行结果和单线程运行的结果是 ...