首页 > 其他分享 >反射与内置方法

反射与内置方法

时间:2023-05-07 21:11:13浏览次数:29  
标签:__ 反射 内置 name ... self print 方法 def

反射

在Python中,反射指的是通过字符串来操作对象的属性,涉及到四个内置函数的使用(Python中一切皆对象,类和对象都可以用下述四个方法)

class Teacher:
    def __init__(self,full_name):
        self.full_name =full_name
 
t=Teacher('jason Lin')
 
# hasattr(object,'name')
hasattr(t,'full_name') # 按字符串'full_name'判断有无属性t.full_name
 
# getattr(object, 'name', default=None)
getattr(t,'full_name',None) # 等同于t.full_name,不存在该属性则返回默认值None
 
# setattr(x, 'y', v)
setattr(t,'age',18) # 等同于t.age=18
 
# delattr(x, 'y')
delattr(t,'age') # 等同于del t.age

基于反射可以十分灵活地操作对象的属性,比如将用户交互的结果反射到具体的功能执行

>>> class FtpServer:
...     def serve_forever(self):
...         while True:
...             inp=input('input your cmd>>: ').strip()
...             cmd,file=inp.split()
...             if hasattr(self,cmd): # 根据用户输入的cmd,判断对象self有无对应的方法属性
...                 func=getattr(self,cmd) # 根据字符串cmd,获取对象self对应的方法属性
...                 func(file)
...     def get(self,file):
...         print('Downloading %s...' %file)
...     def put(self,file):
...         print('Uploading %s...' %file)
... 
>>> server=FtpServer()
>>> server.serve_forever()
input your cmd>>: get a.txt
Downloading a.txt...
input your cmd>>: put a.txt
Uploading a.txt...

内置方法

Python的Class机制内置了很多特殊的方法来帮助使用者高度定制自己的类,这些内置方法都是以双下划线开头和结尾的,会在满足某种条件时自动触发,我们以常用的__str__和__del__为例来简单介绍它们的使用。

__str__方法会在对象被打印时自动触发,print功能打印的就是它的返回值,我们通常基于方法来定制对象的打印信息,该方法必须返回字符串类型

>>> class People:
...     def __init__(self,name,age):
...         self.name=name
...         self.age=age
...     def __str__(self):
...         return '<Name:%s Age:%s>' %(self.name,self.age) #返回类型必须是字符串
... 
>>> p=People('lili',18)
>>> print(p) #触发p.__str__(),拿到返回值后进行打印
<Name:lili Age:18>

__del__会在对象被删除时自动触发。由于Python自带的垃圾回收机制会自动清理Python程序的资源,所以当一个对象只占用应用程序级资源时,完全没必要为对象定制__del__方法,但在产生一个对象的同时涉及到申请系统资源(比如系统打开的文件、网络连接等)的情况下,关于系统资源的回收,Python的垃圾回收机制便派不上用场了,需要我们为对象定制该方法,用来在对象被删除时自动触发回收系统资源的操作

class MySQL:
    def __init__(self,ip,port):
        self.conn=connect(ip,port) # 伪代码,发起网络连接,需要占用系统资源
    def __del__(self):
        self.conn.close() # 关闭网络连接,回收系统资源
 
obj=MySQL('127.0.0.1',3306) # 在对象obj被删除时,自动触发obj.__del__()
__init__ 初始化方法,调用类的时候,自动触发
__str__ 打印或输出对象的时候,自动触发。返回值必须是字符串类型
__repr__ 和str一样,但是优先级低于str
__del__ 删除对象,或者程序全部执行完毕 会自动触发
__doc__ 查看类的信息
class Student():
    """
    这是注释xxxxx
    """
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def __str__(self):
        return 'xxxx'
    def __del__(self):
        print('被删除了')
stu = Student('whx', 18) # 打印 xxxx
print(stu) # 打印 被删除了
print(Student.__doc__) # 打印 这是注释xxxxx


__enter__
__exit__
class MyOpen(object):
    def __init__(self, name):
        self.name = name
    def __enter__(self):
        print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')
    def __exit__(self, exc_type, exc_val, exc_tb):
        # 可以捕捉到异常信息
        print('with中代码执行完毕时执行我')
        print(exc_type) # 异常类型
        print(exc_val) # 异常值
        print(exc_tb) # 追溯信息
        # return True
        # 当返回True的时候,可以忽略下面的raise抛出异常
with MyOpen('a.txt') as f:
    print('=========>')
    raise TypeError('********')  # 主动抛出异常
print('-----------------------------------------') # 若被raise抛出异常,这这句代码不会被执行

__getattr__ #使用句点符获取不存在的属性触发
__setattr__ #使用句点符修改属性,或不存在属性则添加 的时候出发
__delattr__ #使用句点符删除属性的时候触发
class Foo:
    x = 1
    def __init__(self, y):
        self.y = y
    # 查找的属性不存在的时候会执行
    def __getattr__(self, item):
        print('item:%s' % item)
        print('----> from getattr:你找的属性不存在')
    def __setattr__(self, key, value):
        print('----> from setattr')
        print(key, value)
        # self.key = value
        self.__dict__[key] = value
        # self.key = value  # 这就无限递归了
    def __delattr__(self, item):
        print('----> from delattr')
        # del self.item #无限递归了
        self.__dict__.pop(item)


__setitem__
__getitem__
__delitem__
# 使用中括号改值,获取值,删除值的时候自动触发
class Foo:
    def __init__(self, name):
        self.name = name
    def __getitem__(self, item):
        print('__getitem__执行了', item)
        print(self.__dict__[item])
    # 对象中括号改值的时候,会自动触发的,并且,key就是中括号中得key,value就是=右边的值
    def __setitem__(self, key, value):
        print(key, value)
        print('__setitem__执行了')
        self.__dict__[key] = value
    def __delitem__(self, key):
        print('del obj[key]时,我执行')
        self.__dict__.pop(key)
    def __delattr__(self, item):
        print('del obj.key时,我执行')
        self.__dict__.pop(item)

标签:__,反射,内置,name,...,self,print,方法,def
From: https://www.cnblogs.com/ycmyay/p/17380171.html

相关文章

  • 内置模块
    认识模块什么是模块?常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀。但其实import加载的模块分为四个通用类别:1使用python编写的代码(.py文件)2已被编译为共享库或DLL的C或C++扩展3包好一组模块的包4使用C......
  • 数据类型及常用方法
    引入我们学习变量是为了让计算机能够像人一样去记忆事物的某种状态,而变量的值就是用来存储事物状态的,很明显事物的状态分成不同种类的(比如人的年龄,身高,职位,工资等等),所以变量值也应该有不同的类型,例如salary=3.1#用浮点型去记录薪资age=18#用整型去记录年龄name='lil......
  • 挂载NTFS分区,离线安装NTFS-3G(Linux挂载NTFS格式磁盘的方法)
    挂载NTFS分区,离线安装NTFS-3G(Linux挂载NTFS格式磁盘的方法)本文档环境为centos7.9版本目录挂载NTFS分区,离线安装NTFS-3G(Linux挂载NTFS格式磁盘的方法)一、NTFS-3G说明二、在线安装(有网络环境)三、离线安装(无网络环境)1单独下载软件包(gcc、ntfs-3g)2将下载的软件包传输目标虚拟机(......
  • 在访问UserController控制器下的connonParam方法的时候无法访问,报404
    在访问UserController控制器下的connonParam方法的时候无法访问,报404服务已经起来了  但是访问还是失败了找不到资源 springmvc配置类也配好了路径,最后发现是 ServletContainersInitConfig的getServletMappings()方法没有设置交由springmvc的拦截请求,修改! ......
  • element中表格的另一种显示方法
    正常(默认展示该数据的相关属性值):      <el-table-column       prop="name"       label="姓名"       width="180"      ></el-table-column>转换法(去掉prop属性,改为用值判断显示内容):     ......
  • 微信小程序在wxml里不支持includes,indexOf,findIndex等方法
    小程序的wxml文件内不支持数组的includes,indexOf,findIndex等方法。不是垃圾是什么?玩什么标新立异?不会搞就别TM搞。 开发者:我想上二楼。WX:这里有一坨屎,吃子它,就让你上二楼。开发者:@#$%&@^$*^&*&^$%$^ 咋做?在任意目录创建一个.wxs文件,里面写上如下代码:文件-/utils/wuti......
  • Pandas内置函数方法
    1.导入数据:pd.read_csv(filename):从CSV文件导入数据pd.read_table(filename):从限定分隔符的文本文件导入数据pd.read_excel(filename):从Excel文件导入数据pd.read_sql(query,connection_object):从SQL表/库导入数据pd.read_json(json_string):从JSON格式的字符......
  • Windows下SYSTEM权限文件夹的删除方法
    (不一定对所有情况都能用..。但是目前发现比较简单有效...)以C:/Windows.old文件夹为例,一般来说都无法完全删除,到最后总会提示需要SYSTEM权限。怎么办呢,下载一个VSCode,然后用VSCode打开Windows.old文件夹,便可采用VSCode将该文件夹下的所有内容删除干净...(我也不知道原理,但是属......
  • MultiDex使用方法及由此导致的crash、ANR问题解决方案
    Android开发的朋友,如果是在开发一款中大型应用时,都会碰到这么一个问题,就是dex分拆问题,google给出的解决方案MultiDex。现象:有些APP本身功能比较多,再加上一些其它三方的SDK,慢慢的发现dex越来越大,直到有一天编译出现如下错误:Error:Thenumberofmethodreferencesina.dexfile......
  • Ubuntu sudo不用输入密码的方法
    在启动时进入安全模式,这时是用root登录的,执行:chmod740/etc/sudoers然后打开/etc/sudoers这个文件,把最后一行:#UserprivilegespecificationrootALL=(ALL:ALL)ALL#Allowmembersofgroupsudotoexecuteanycommand%sudoALL=(ALL:ALL)ALL改为 #Use......