双下方法

定义:双下方法是特殊方法,他是解释器提供的 由爽下划线加方法名加双下划线 __方法名__的具有特殊意义的方法,双下方法主要是python源码程序员使用的,我们在开发中尽量不要使用双下方法,但是深入研究双下方法,更有益于我们阅读源码。

调用:不同的双下方法有不同的触发方式,就好比盗墓时触发的机关一样,不知不觉就触发了双下方法,例如:init

## __len__

class B:def __len__(self):print(666)b = B()
len(b) # len 一个对象就会触发 __len__方法。class A:def __init__(self):self.a = 1self.b = 2def __len__(self):return len(self.__dict__)
a = A()
print(len(a))

## __hash__

class A:def __init__(self):self.a = 1self.b = 2def __hash__(self):return hash(str(self.a)+str(self.b))
a = A()
print(hash(a))

## __str__

如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。

class A:def __init__(self):passdef __str__(self):return '太白'
a = A()
print(a)
print('%s' % a)

## __repr__

如果一个类中定义了__repr__方法,那么在repr(对象) 时,默认输出该方法的返回值。

class A:def __init__(self):passdef __repr__(self):return '太白'
a = A()
print(repr(a))
print('%r'%a)

## __call__

对象后面加括号,触发执行。

注:构造方法__new__的执行是由创建对象触发的,即:对象 = 类名() ;而对于 call 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

class Foo:def __init__(self):passdef __call__(self, *args, **kwargs):print('__call__')obj = Foo() # 执行 __init__
obj()       # 执行 __call__

## __eq__

class A:def __init__(self):self.a = 1self.b = 2def __eq__(self,obj):if  self.a == obj.a and self.b == obj.b:return True
a = A()
b = A()
print(a == b)

## __del__

析构方法,当对象在内存中被释放时,自动触发执行。

注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

## __new__

class A:def __init__(self):self.x = 1print('in init function')def __new__(cls, *args, **kwargs):print('in new function')return object.__new__(A, *args, **kwargs)a = A()
print(a.x)
class A:__instance = Nonedef __new__(cls, *args, **kwargs):if cls.__instance is None:obj = object.__new__(cls)cls.__instance = objreturn cls.__instance

单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。
【采用单例模式动机、原因】
对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器。如在Windows中就只能打开一个任务管理器。如果不使用机制对窗口对象进行唯一化,将弹出多个窗口,如果这些窗口显示的内容完全一致,则是重复对象,浪费内存资源;如果这些窗口显示的内容不一致,则意味着在某一瞬间系统有多个状态,与实际不符,也会给用户带来误解,不知道哪一个才是真实的状态。因此有时确保系统中某个对象的唯一性即一个类只能有一个实例非常重要。
如何保证一个类只有一个实例并且这个实例易于被访问呢?定义一个全局变量可以确保对象随时都可以被访问,但不能防止我们实例化多个对象。一个更好的解决办法是让类自身负责保存它的唯一实例。这个类可以保证没有其他实例被创建,并且它可以提供一个访问该实例的方法。这就是单例模式的模式动机。
【单例模式优缺点】
【优点】
一、实例控制
单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。
二、灵活性
因为类控制了实例化过程,所以类可以灵活更改实例化过程。
【缺点】
一、开销
虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题。
二、可能的开发混淆
使用单例对象(尤其在类库中定义的对象)时,开发人员必须记住自己不能使用new关键字实例化对象。因为可能无法访问库源代码,因此应用程序开发人员可能会意外发现自己无法直接实例化此类。
三、对象生存期
不能解决删除单个对象的问题。在提供内存管理的语言中(例如基于.NET Framework的语言),只有单例类能够导致实例被取消分配,因为它包含对该实例的私有引用。在某些语言中(如 C++),其他类可以删除对象实例,但这样会导致单例类中出现悬浮引用

## __item__系列

class Foo:def __init__(self,name):self.name=namedef __getitem__(self, item):print(self.__dict__[item])def __setitem__(self, key, value):self.__dict__[key]=valuedef __delitem__(self, key):print('del obj[key]时,我执行')self.__dict__.pop(key)def __delattr__(self, item):print('del obj.key时,我执行')self.__dict__.pop(item)f1=Foo('sb')
f1['age']=18
f1['age1']=19
del f1.age1
del f1['age']
f1['name']='alex'
print(f1.__dict__)

上下文管理器相关

__enter__ __exit__

# 如果想要对一个类的对象进行with  as 的操作 不行。
class A:def __init__(self, text):self.text = textwith A('大爷') as f1:print(f1.text)
class A:def __init__(self, text):self.text = textdef __enter__(self):  # 开启上下文管理器对象时触发此方法self.text = self.text + '您来啦'return self  # 将实例化的对象返回f1def __exit__(self, exc_type, exc_val, exc_tb):  # 执行完上下文管理器对象f1时触发此方法self.text = self.text + '这就走啦'with A('大爷') as f1:print(f1.text)
print(f1.text)
class Diycontextor:def __init__(self,name,mode):self.name = nameself.mode = modedef __enter__(self):print "Hi enter here!!"self.filehander = open(self.name,self.mode)return self.filehanderdef __exit__(self,*para):print "Hi exit here"self.filehander.close()with Diycontextor('py_ana.py','r') as f:for i in f:print i

相关面试题:

class StarkConfig:def __init__(self,num):self.num = numdef run(self):self()def __call__(self, *args, **kwargs):print(self.num)class RoleConfig(StarkConfig):def __call__(self, *args, **kwargs):print(345)def __getitem__(self, item):return self.num[item]v1 = RoleConfig('alex')
v2 = StarkConfig('太白金星')
# print(v1[1])
# print(v2[2])
v1.run()-------
class UserInfo:passclass Department:passclass StarkConfig:def __init__(self, num):self.num = numdef changelist(self, request):print(self.num, request)def run(self):self.changelist(999)class RoleConfig(StarkConfig):def changelist(self, request):print(666, self.num)class AdminSite:def __init__(self):self._registry = {}def register(self, k, v):self._registry[k] = vsite = AdminSite()
site.register(UserInfo, StarkConfig)
# 1
# obj = site._registry[UserInfo]()# 2
obj = site._registry[UserInfo](100)
obj.run()-------
class UserInfo:passclass Department:passclass StarkConfig:def __init__(self,num):self.num = numdef changelist(self,request):print(self.num,request)def run(self):self.changelist(999)class RoleConfig(StarkConfig):def changelist(self,request):print(666,self.num)class AdminSite:def __init__(self):self._registry = {}def register(self,k,v):self._registry[k] = v(k)site = AdminSite()
site.register(UserInfo,StarkConfig)
site.register(Department,RoleConfig)for k,row in site._registry.items():row.run()-------
class A:list_display = []def get_list(self):self.list_display.insert(0,33)return self.list_displays1 = A()
print(s1.get_list())-------
class A:list_display = [1, 2, 3]def __init__(self):self.list_display = []def get_list(self):self.list_display.insert(0, 33)return self.list_displays1 = A()
print(s1.get_list())------
class A:list_display = []def get_list(self):self.list_display.insert(0,33)return self.list_displayclass B(A):list_display = [11,22]s1 = A()
s2 = B()
print(s1.get_list())
print(s2.get_list())

转载于:https://www.cnblogs.com/Jacob-yang/p/11191790.html

Python之面相对象 - 双下方法相关推荐

  1. python中常见的双下方法_python中常见的双下方法_python面向对象(5)__特殊双下方法...

    双下方法 双下方法是开发python这个语言程序员用的,源码中使用的. 我们不能轻易使用双下方法.可能重新写object的源码,慎用!!! 双下方法特征:你不知道干啥了,就会触发某个双下方法 len ...

  2. python 面向对象之:反射,双下方法

    函数vs 方法 # 1 通过函数名可以大致判断 # print(func) # <function func at 0x00000000005D1EA0> 函数 # obj = A() # ...

  3. Python面向对象06/反射/双下方法

    目录 day 26 /反射,双下方法 目录 1.元类type 2.反射 3.函数与类的区别 4.特殊的双下方法 day 26 /反射,双下方法 目录 1.元类type type:获取对象从属的类Pyt ...

  4. Python之面相对象 - 函数VS方法 反射

    函数VS方法 从分类的角度来分析. (1)函数的分类: 内置函数:python内嵌的一些函数. 匿名函数:一行代码实现一个函数功能. 递归函数 自定义函数:根据自己的需求,来进行定义函数. (2)方法 ...

  5. Python面向对象反射,双下方法

    一. 反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序 ...

  6. python之路-双下方法

    双下方法 定义: 双下方法是特殊方法,他是解释器提供的,由双下线加方法名加双下划线 __方法名__具有特殊意义的方法 双下方法主要是Python源码程序员使用的,元编程 我们在开发中尽量不要使用双下方 ...

  7. python之面向对象反射和双下方法

    面向对象之反射,双下方法 反射 定义:主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省) python面向对象中的反射:通过字符串的形式操作对象相关的属性.python中一切皆对象(都 ...

  8. Python 第二十六章 面向对象 元类+反射+双下方法

    元类 class A:pass obj = A() print(type('abc')) print(type([1,2,3])) print(type((22,33)))# type 获取对象从属于 ...

  9. Python学习,元类type 反射 函数与方法 双下方法

    1.元类type type 获取对象从属于的类 python 中 一切皆对象, 类在某种意义上也是一个对象, python中自己定义的类, 以及大部分内置类, 都是由type元类(构建类)实例化得来的 ...

最新文章

  1. java 中美时间_求教用java编写一个程序要求给定一个日期值,计算若干天后的日期值,和给定两个日期计算它们之间相距的天...
  2. 检查CentOS7定时任务是否启用并执行过
  3. matlab球面波衍射,单色点源矩孔菲涅耳衍射光场的计算与模拟
  4. codevs 2185 最长公共上升子序列--nm的一维求法
  5. 【C++】int与string转换
  6. linux系统时间函数,Linux时间时区详解与常用时间函数
  7. SpringBoot——@Scheduled的自定义周期性线程池解决任务延时执行问题
  8. javaweb框架--自定义标签与freemaker结合
  9. [bzoj1412][ZJOI2009]狼和羊的故事
  10. 快速攻克机器学习图像异常检测
  11. 建立本地rhel5.3的yum源
  12. Leetcode 106.从中序与后序遍历序列重建二叉树
  13. Python高阶函数-闭包
  14. Adobe Illustrator for Mac 2020 24.0.1版 — 矢量绘图工具
  15. 【编程开发】之 Java 实现邮件发送
  16. 漫谈程序员系列 薪资,你是我不能言说的伤
  17. 微信小程序传数组给后台(thinkphp后台接受前端数组参数)
  18. 视频变声音的软件有哪些?剪辑视频怎么改变声音
  19. java 二嗨租车项目_Java第二季租车系统参考
  20. 无root 权限 linux安装 rar,centos上如何yum安装rar/unrar及手动安装最新rar

热门文章

  1. 【合泰HT3252352串口通信实验注意点】
  2. 为华生物PCL-NH2 聚己内酯氨基的简介及应用说明
  3. Shopro商城,基于Fastadmin和Uniapp进行开发的多平台(微信公众号、微信小程序、H5网页、Android-App、IOS-App)购物商城
  4. 爬虫爬取emoji图片数据
  5. 树立感恩心态 追求卓越人生
  6. 嵌入式系统下Microwindows的实现
  7. 工作常用工作管理软件介绍
  8. C++类中有如vector, map等容器类成员时如何编写构造函数
  9. 软件测试入职一年多薪资正常应该有多少?
  10. 2018ccpc吉林 C:JUSTICE 思维