一.反射

反射:程序可以访问,检测和修改它本身状态或行为的一种能力(自省)

python面向对象中的反射:通过字符串的形式操作对象相关的属性

python中的一切事物都是对象(都可以使用反射)

四个可以实现自省的函数,下列方法适用于类和对象(一切对象,类本身也是对象)

# 对实例化对象的示例
class Foo:f = '类的静态变量'def __init__(self, name, age):self.name = nameself.age = agedef say_hi(self):print(f'Hi,{self.name}')
obj = Foo('小马', 18)# 检测是否含有某属性
print(hasattr(obj, 'name'))  # True
print(hasattr(obj, 'say_hi'))# 获取属性
n = getattr(obj, 'name')
print(n)
func = getattr(obj, 'say_hi')
func()
print(getattr(obj, 'aaa', '不存在啊')) # 没有会返回设定好的信息,不设定则报错# 设置属性
setattr(obj, 'hello', True) # 设置字段 hello = True
setattr(obj, 'show_name', lambda self: self.name + '美女') # 设置方法
print(obj.__dict__)
print(obj.show_name(obj)) # 设置的函数也在对象空间中# 删除属性
delattr(obj, 'age')
delattr(obj, 'show_name')
delattr(obj, 'show_name111') # 不存在就会报错print(obj.__dict__)
-----------------------------------------------------
# 对类的反射
class Foo:Class_name = '天上人间'def __init__(self, name):self.name = namedef func(self):return 'func'@staticmethoddef bar():return 'bar'print(getattr(Foo, 'Class_name'))
print(getattr(Foo, 'func'))
print(getattr(Foo, 'bar'))
-----------------------------------------------------# 当前模块的反射
import sys
def s1():print('s1')
def s2():print('s2')this_module = sys.modules[__name__] # 获取当前脚本这个对象
print(hasattr(this_module, 's1'))
a = getattr(this_module, 's2')
a()
-----------------------------------------------------
# 其他模块的发射
# 一个模块中代码(module_test.py)
def test():print('from the test')# 本模块中的代码
import module_test as obj
obj.test()
print(hasattr(obj, 'test'))
a = getattr(obj, 'test')
a()
-----------------------------------------------------
# 反射的应用
# 模拟访问网站
class User:def login(self):print('欢迎来到登录页面')def register(self):print('欢迎来到注册页面')def save(self):print('欢迎来到存储页面')user = User()
while 1:choose = input('>>>:').strip()if hasattr(user, choose):func = getattr(user, choose)func()else:print('输入错误!')

二.函数VS方法

1.判断函数与方法的途径

通过打印函数(方法)名确定

'''
学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:725638078
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def func():passprint(func)  # <function func at 0x01CCF7C8>class A:def func(self):passprint(A.func)  # <function A.func at 0x03AAA588>
obj = A()
print(obj.func)
# <bound method A.func of <__main__.A object at 0x01D05450>>

通过types模块验证

from types import FunctionType
from types import MethodTypedef func():passclass A:def func(self):passobj = A()
print(isinstance(func, FunctionType))  # True
print(isinstance(A.func, FunctionType))  # True
print(isinstance(obj.func, FunctionType))  # False
print(isinstance(obj.func, MethodType))  # True
---------------------------------------------------
# 静态方法是函数
from types import FunctionType
class A:def func(self):pass@classmethoddef func1(self):pass@staticmethoddef func2(self):pass
obj = A()
# 静态方法其实是函数
print(isinstance(A.func2, FunctionType))  # True
print(isinstance(obj.func2, FunctionType))  # True

2.函数与方法的区别

  • 函数是显性传参,如我们要指明为len()函数传递一些要处理的参数 !
  • 函数跟对象无关 !
  • 方法中存在隐式传参 !
  • 方法可以操作类内部的数据
  • 方法跟对象是关联的.如我们在用strip()方法是,是不是都是要通过str对象调用,比如我们有字符串s,然后s.strip()这样调用.是的,strip()方法属于str对象

三.双下方法

1.定义:

双下方法是特殊方法,他是解释器提供的,由双下划线加方法名加双下划线(方法名)组成具有特殊意义的方法,双下方法主要是python源码程序员使用的

2.调用:

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

3.__init__

class A:def __init__(self, name):print('in __init__')self.name = name
obj = A('小马')
# 实例化对象时自动运行,在__new__之后

4.__len__

'''
学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:725638078
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
# 一个对象可以使用len()函数,根本原因是这个对象从属于的类中有__len__方法
class B:def __len__(self):print(666)return 10  # 必须要有一个int型的返回值b = B()
len(b) # len()一个对象就会触发__len__方法  # 666class A:def __init__(self):self.a = 1self.b = 2def __len__(self):return len(self.__dict__)a = A()
print(len(a))  # 2

5.__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))  # hash()一个对象就会触发__hash__方法

6.__str__

# 如果一个类中定义了__str__方法,那么在打印对象时,默认输出该方法的返回值
class A:def __init__(self, name):self.name = namedef __str__(self):return self.name
a = A('小马')
str(a) # str()一个对象就会触发__str__方法
print(str(a))
print(a) # 打印对象时,默认输出__str__方法的返回值
print(f'{a}') # 格式化输出也会触发__str__方法

7.__repr____str__相似,但是优先级比__str__

'''
学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:725638078
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class A:def __init__(self):passdef __repr__(self):return '小马'
a = A()
print(repr(a))
print(a) # 打印对象时,也可以调用__repr__方法
print(f'{a}') # 格式化输出,也可以调用__repr__方法
print('%r' % a) # 指定调用__repr__方法

8.__call__

# 对象后面加括号,触发执行
# 注:构造方法__new__的执行是由创建对象触发的,即:对象 = 类名(),而对于__call__方法的执行是由对象后加括号触发的,即:对象(),或者类()()
class Foo:def __init__(self):passdef __call__(self, *args, **kwargs):print('__call__')
obj = Foo()  # 执行 __init__
obj()  # 执行 __call__

9.__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) # 对一个类的两个对象进行比较操作就会触发__eq__方法

10.__del__

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

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

11.__new__构造方法,创造并返回一个新对象

class A:def __init__(self):self.x = 1print('in init function')def __new__(cls, *args, **kwargs):print('in new function')return object.__new__(cls)# 调用object或者父类(最终调用object)的__new__来开辟对象空间a = A() # 类名加()先触发__new__,并且将类名自动传给cls
print(a.x)
-------------------------------------------------------
# 单例模式
# 一个类只能实例化一个对象,无论实例化多少次,内存中只有一个对象;这个类的对象不是个性化的,主要是实例化对象之后去执行类中的方法
class A:__instance = Nonedef __new__(cls, *args, **kwargs):if cls.__instance is None:obj = object.__new__(cls)cls.__instance = objreturn cls.__instancedef func(self):print(self.__instance)
a = A()
a.func() # <__main__.A object at 0x002F5F30>b = A() # b还是a对象
print(b is a) # True

单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源.如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案.

采用单例模式动机,原因: 对于系统中的某些类来说,只有一个实例很重要.例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器.如在Windows中就只能打开一个任务管理器.如果不使用机制对窗口对象进行唯一化,将弹出多个窗口,如果这些窗口显示的内容完全一致,则是重复对象.浪费内存资源;如果这些窗口显示的内容不一致,则意味着在某一瞬间系统有多个状态,与实际不符,也会给用户带来误解,不知道哪一个才是真实的状态.因此有时确保系统中某个对象的唯一性即一个类只能有一个实例非常重要.

如何保证一个类只有一个实例并且这个实例易于被访问呢? 定义一个全局变量可以确保对象随时都可以被访问,但不能防止我们实例化多个对象.一个更好的解决办法是让类自身负责保存它的唯一实例.这个类可以保证没有其他实例被创建,并且它可以提供一个访问该实例的方法.这就是单例模式的模式动机.

单例模式优缺点

# 单例模式优缺点
# 优点
# 一,实例控制
# 单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例.
# 二,灵活性
# 因为类控制了实例化过程,所以类可以灵活更改实例化过程.# 缺点
# 一,开销
# 虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销.可以通过使用静态初始化解决此问题.
# 二,可能的开发混淆
# 使用单例对象(尤其在类库中定义的对象)时,开发人员必须记住自己不能使用new关键字实例化对象.因为可能无法访问库源代码,因此应用程序开发人员可能会意外发现自己无法直接实例化此类.
# 三,对象生存期
# 不能解决删除单个对象的问题.

12.__item__系列 对对象进行类似字典的操作

'''
学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:725638078
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class Foo:def __init__(self, name):self.name = namedef __getitem__(self, item):print(self.__dict__[item])print(666)def __setitem__(self, key, value):self.__dict__[key] = valuedef __delitem__(self, key):self.__dict__.pop(key)print('del obj[key]时,我执行')def __delattr__(self, item):print('del obj.key时,我执行')self.__dict__.pop(item)
f1 = Foo('小马')
f1['age'] = 18 # 执行__setitem__方法
f1['sex'] = '男'
print(f1['age']) # 执行__getitem__方法
del f1['age']  # 执行__delitem__方法
del f1.sex     # 执行__delattr__方法
f1['name'] = '大马'
print(f1.__dict__)

13.__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):  # 开启上下文管理器(with语句)对象时触发此方法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('in enter')self.filehander = open(self.name, self.mode)return self.filehanderdef __exit__(self, *para):print('in exit')self.filehander.close()with Diycontextor('module_test.py', 'r') as f:for i in f:print(i)

结尾给大家推荐一个非常好的学习教程,希望对你学习Python有帮助!

Python基础入门教程推荐

Python爬虫案例教程推荐

Python面向对象中反射和双下的正确用法相关推荐

  1. 面向对象之: 反射和双下方法

    目录 一, 反射 二, 函数VS方法 三, 双下方法 一, 反射 反射:程序可以访问,检测和修改它本身状态或行为的一种能力(自省) python面向对象中的反射:通过字符串的形式操作对象相关的属性 p ...

  2. python基础中apply()函数的正确用法

    函数格式为:apply(func,*args,**kwargs) 用途:当一个函数的参数存在于一个元组或者一个字典中时,用来间接的调用这个函数,并肩元组或者字典中的参数按照顺序传递给参数 解析:arg ...

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

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

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

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

  5. 06 面向对象之:反射,双下方法

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

  6. Python面向对象中的“私有化”

    Python面向对象中的"私有化" Python并不直接支持私有方式,而要靠程序员自己把握在外部进行特性修改的时机. 为了让方法或者特性变为私有(从外部无法访问),只要在它的名字前 ...

  7. Python - 面向对象编程 - 反射 hasattr、getattr、getattr、delattr

    什么是反射 反射的概念是由 Smith 在 1982 年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省) Python 面向对象中的反射 通过字符串的形式操作对象的属性 ...

  8. 【Python基础】关于Python的前后、单双下划线作用

    python的各种下划线 在Python中,可能最常见的就是各种常量.变量.函数.方法前后添加的那些下划线了.有前面加的.后面加的,加一个的,加两个的,看到头晕.那么,你对这些知识都掌握了吗 ?让我们 ...

  9. 关于Python的前后、单双下划线作用,看完这篇文章,吊打面试官!

    Python实战社群 Java实战社群 长按识别下方二维码,按需求添加 扫码关注添加客服 进Python社群▲ 扫码关注添加客服 进Java社群▲ 作者丨王翔丨 来源丨清风Python(ID:Bree ...

最新文章

  1. tar xvf实现的是什么功能呢?
  2. .NET 调用JS:WebBrowser.Document.InvokeScript 方法抛出“指定的转换无效”异常的原因
  3. purrr 0.2.0
  4. android - Drawable - ColorDrawable 学习笔记
  5. 如何准备Java初级和高级的技术面试
  6. java, android的aes等加密库
  7. Netty游戏服务器二
  8. Linux下Gogs二进制安装配置
  9. 华南农业大学计算机科学与技术专业,华南农业大学住宿
  10. 精品软件 推荐 淘宝 天猫 秒杀助手
  11. BAT批处理脚本实例学习(三)清理系统垃圾
  12. 基于KNN的垃圾邮件分类实验
  13. NLP文本分类--词向量
  14. BFS宽度优先搜索(新冠病毒的传播)
  15. 0基础学c语言txt下载,0基础学C语言.doc
  16. 富爸爸系列2—财务自由之路
  17. 初学oracle笔记
  18. 【加密锁】Virbox对Unity3D打包程序加密流程
  19. php 选择地区 查找,地区编码查询_php根据ip查询所在地区的代码
  20. 【逐梦云服务平台研究之redis启动】

热门文章

  1. GT考试(bzoj 1009)
  2. 10.Spark之RDD及编程接口
  3. 【Shall脚本】定时在线备份上传
  4. 安装sun-java5-jdk 在ubuntu 9.10 提示无法找到软件包sun-java5-jdk#...
  5. WebPart(汇总)[转载]
  6. spring3.x企业应用开发实战 pdf_吃透Spring全家桶:Spring源码+SpringBoot+SpringCloud实战...
  7. 【学习笔记】项目Leader如何成长
  8. WSAEWOULDBLOCK: Resource temporarily unavailable
  9. 使用特殊的技术更新数据库(ABAP)
  10. Segment-段(SAP)