python的getattr和getattribute拦截内置操作实现

 更新时间:2024年01月16日 09:37:36   作者:梯阅线条  
在Python中,getattr和getattribute是用于动态属性访问和自定义属性访问行为的重要工具,本文主要介绍了python的getattr和getattribute拦截内置操作实现,具有一定的参考价值,感兴趣的可以了解一下

1.1 特性描述符getattr(bute)管理属性比较

描述

特性和描述符,管理属性时,实例属性用前单下划线开头,self._attr。

__getattr__(),管理属性时,未定义属性的点号运算返回已定义属性的点号运算。

__getattribute__(),管理属性时,用object.__getattribute__(self,name,value),避免循环。

示例

>>> class SquareCubePro:
    '''
        property 特性计算平方和立方
        前下化线开头属性名存储基础数据
        赋值为特性的属性名不带下划线
        self._square和square=property:
        实例属性和特性属性不能同名,避免循环
    '''
    def __init__(self,sq,cu):
        self._square=sq
        self._cube=cu
    def getSquare(self):
        return self._square**2
    def setSquare(self,value):
        self._square=value
    square=property(getSquare,setSquare)
    
    def getCube(self):
        return self._cube**3
    cube=property(getCube)

    
>>> scp=SquareCubePro(2,3)
>>> scp.square,scp.cube
(4, 27)
>>> scp=SquareCubePro(3,5)
>>> scp.square,scp.cube
(9, 125)
>>> scp.square=5
>>> scp.square
25



>>> class SquareDesc:
    '''
        Descriptor 描述符计算平方和立方
        基础数据存储在客户类实例的属性上
    '''
    def __get__(self,instance,owner):
        return instance._square**2
    def __set__(self,instance,value):
        instance._square=value

        
>>> class CubeDesc:
    def __get__(self,instance,owner):
        return instance._cube**3

    
>>> class SquareCubeDesc:
    sq=SquareDesc()
    cu=CubeDesc()
    def __init__(self,sq,cu):
        self._square=sq
        self._cube=cu

        
>>> scd=SquareCubeDesc(3,5)
>>> scd.sq,scd.cu
(9, 125)
>>> scd.sq=5
>>> scd.sq
25

>>> class SquareCubeGetA:
    '''
        重载 __getattr__ 计算平方和立方
    '''
    def __init__(self,sq,cu):
        self._square=sq
        self._cube=cu
    def __getattr__(self,name):
        if name=='square':
            return self._square**2
        elif name=='cube':
            return self._cube**3
        else:
            raise TypeError('属性错误:',name)
    def __setattr__(self,name,value):
        if name=='square':
            self.__dict__['_square']=value
        else:
            self.__dict__[name]=value

            
>>> scga=SquareCubeGetA(3,5)
>>> scga.square,scga.cube
(9, 125)
>>> scga.square=5
>>> scga.square
25

>>> class SquareCubeGetAB:
    '''
        重载 __getattribute__ 计算平方和立方
    '''
    def __init__(self,sq,cu):
        self._square=sq
        self._cube=cu
    def __getattribute__(self,name):
        if name=='square':
            return object.__getattribute__(self,'_square')**2
        elif name=='cube':
            return object.__getattribute__(self,'_cube')**3
        else:
            return object.__getattribute__(self,name)
    def __setattr__(self,name,value):
        if name=='square':
            self.__dict__['_square']=value
        else:
            self.__dict__[name]=value

            
>>> scgab=SquareCubeGetAB(3,5)
>>> scgab.square,scgab.cube
(9, 125)
>>> scgab.square=5
>>> scgab.square
25

1.2 getattr和getattribute拦截内置操作

python内置操作和对应方法。

NO内置操作对应方法
1索引操作[i]__getitem__
2加法(连接)操作+__coerce__ __add__
3括号调用()__call__
4打印print()__str__

__coerce__:表示强制类型转换,使用加法(或连接)操作+时,不同类型会触发类型转换或者报错。

1.2.1 S.center(width[, fillchar]) -> string

用法

S.center(width[, fillchar]) -> string

描述

python的s.center()使字符串居中对齐。

S:字符串;

width:字符串宽度;

fillchar:填充字符,字符串长度小于width时生效,否则不生效。

示例

>>> strL=['MyGetAttr','MyGetAttribute']
>>> for s in strL:
    print('\n'+s.center(50,'='))
    print('test center')

====================MyGetAttr=====================
test center

==================MyGetAttribute==================
test center

1.2.2 testgetattr.py

# encoding:utf-8

class MyGetAttr:
    name='梯阅线条'
    def __init__(self):
        self.url='tyxt.work'
    def __len__(self):
        print('__len__:9555')
        return 9555
    def __getattr__(self,attr):
        print('__getattr__:'+attr)
        if attr == '__str__':
            return lambda *args:'[GetAttr str]'
        else:
            return lambda *args:None

        
class MyGetAttribute(object):
    name='梯阅线条'
    def __init__(self):
        self.url='tyxt.work'
    def __len__(self):
        print('__len__:9555')
        return 9555
    def __getattribute__(self,attr):
        print('__getattribute__:'+attr)
        if attr == '__str__':
            return lambda *args:'[Getattribute str]'
        else:
            return lambda *args:None

if __name__=='__main__':     
    import sys
    print('python '+sys.version.split()[0])
    for C in MyGetAttr,MyGetAttribute:
        print('\n'+C.__name__.center(50,'='))
        c1=C()
        c1.name
        c1.url
        c1.tel
        len(c1)
        try:
            c1[0]
        except:
            print('fail []')
        try:
            c1+99
        except:
            print('fail +')
        try:
            c1()
        except:
            print('fail ()')
        c1.__call__()
        print(c1.__str__())
        print(c1)

1.2.3 python2.x的getattr和getattribute拦截内置操作

python2.x的__getattr__()拦截未定义属性操作,包括当前类内未定义的seq[i]、+、()、print()等内置操作。

python2.x的__getattribute__()拦截全部属性的点号运算、赋值运算、删除属性,不拦截当前类内未定义的seq[i]、+、()、print()等内置操作。

NO调用方式是否被__getattr__()拦截是否被__ getattribute __()拦截
1print(实例名)被拦截不被拦截
2实例名.__str__()被拦截被拦截
3实例名()被拦截不被拦截
4实例名.__call__()被拦截被拦截
5[]、+被拦截不被拦截

在cmd执行结果如下:

C:\Users\Administrator>D:\Python27\python.exe E:\documents\F盘\testgetattr.py
python 2.7.18

====================MyGetAttr=====================
__getattr__:tel
__len__:9555
__getattr__:__getitem__
__getattr__:__coerce__
__getattr__:__add__
__getattr__:__call__
__getattr__:__call__
__getattr__:__str__
[GetAttr str]
__getattr__:__str__
[GetAttr str]

==================MyGetAttribute==================
__getattribute__:name
__getattribute__:url
__getattribute__:tel
__len__:9555
fail []
fail +
fail ()
__getattribute__:__call__
__getattribute__:__str__
[Getattribute str]
<__main__.MyGetAttribute object at 0x00000000034B7C88>

1.2.4 python3.x的getattr和getattribute拦截内置操作

python3.x的__getattr__()拦截未定义属性操作,不拦截当前类内未定义的seq[i]、+、()、print()等内置操作。

python3.x的__getattribute__()拦截全部属性的点号运算、赋值运算、删除属性,不拦截当前类内未定义的seq[i]、+、()、print()等内置操作。

python3.x中,MyGetAttr未定义__str__(),但都未被__getattr__()拦截,因为从object继承了__str__()方法,所以不会被拦截。通过hasattr(MyGetAttr,‘__str__’)返回True验证。

python3.x中,MyGetAttribute未定义__str__(),通过print()打印不会被拦截,显式调用会被拦截。

python3.x中,调用小括号(),即__call__,不会被__getattr__()和__getattribute__()拦截,显式调用会被拦截。

NO调用方式是否被__getattr__()拦截是否被__ getattribute __()拦截
1print(实例名)不被拦截不被拦截
2实例名.__str__()不被拦截被拦截
3实例名()不被拦截不被拦截
4实例名.__call__()被拦截被拦截
5[]、+不被拦截不被拦截

在cmd执行结果如下:

C:\Users\Administrator>D:\Python3\python.exe E:\documents\F盘\testgetattr.py
python 3.7.8

====================MyGetAttr=====================
__getattr__:tel
__len__:9555
fail []
fail +
fail ()
__getattr__:__call__
<__main__.MyGetAttr object at 0x01648E10>
<__main__.MyGetAttr object at 0x01648E10>

==================MyGetAttribute==================
__getattribute__:name
__getattribute__:url
__getattribute__:tel
__len__:9555
fail []
fail +
fail ()
__getattribute__:__call__
__getattribute__:__str__
[Getattribute str]
<__main__.MyGetAttribute object at 0x01648F50>

到此这篇关于python的getattr和getattribute拦截内置操作实现的文章就介绍到这了,更多相关python的getattr和getattribute拦截内置内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • python安装包出现SSL证书验证失败​的问题及解决方式

    python安装包出现SSL证书验证失败​的问题及解决方式

    安装modelscope时SSL证书验证失败,原因为代理设置干扰了连接,关闭代理后成功安装,说明代理可能影响SSL握手,建议排查代理配置,优先尝试关闭代理解决此类问题
    2025-08-08
  • 详解使用Pytorch Geometric实现GraphSAGE模型

    详解使用Pytorch Geometric实现GraphSAGE模型

    这篇文章主要为大家介绍了详解使用Pytorch Geometric实现GraphSAGE模型示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • Python包管理利器之pip命令的安装与使用入门指南

    Python包管理利器之pip命令的安装与使用入门指南

    pip是Python的包管理工具,全称为"Pip Installs Packages",是Python生态系统中最重要的工具之一,下面就跟随小编一起深入了解下pip命令的安装与使用吧
    2025-04-04
  • 关于python中第三方库交叉编译的问题

    关于python中第三方库交叉编译的问题

    这篇文章主要介绍了python及第三方库交叉编译,通过交叉编译工具,我们就可以在CPU能力很强、存储控件足够的主机平台上(比如PC上)编译出针对其他平台的可执行程序,需要的朋友可以参考下
    2022-09-09
  • python之链表的反转方式

    python之链表的反转方式

    这篇文章主要介绍了python之链表的反转方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • Python在实时数据流处理中集成Flink与Kafka

    Python在实时数据流处理中集成Flink与Kafka

    随着大数据和实时计算的兴起,实时数据流处理变得越来越重要,Flink和Kafka是实时数据流处理领域的两个关键技术,下面我们就来看看如何使用Python将Flink和Kafka集成在一起吧
    2025-03-03
  • 人工智能学习Pytorch教程Tensor基本操作示例详解

    人工智能学习Pytorch教程Tensor基本操作示例详解

    这篇文章主要为大家介绍了人工智能学习Pytorch教程Tensor的基本操作示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2021-11-11
  • Python解析Excel图表Chart的信息实战指南

    Python解析Excel图表Chart的信息实战指南

    在数据分析与报表自动化场景中,Excel图表往往承载着关键业务信息,本文将基于OpenXML规范,通过将.xlsx文件视为ZIP压缩包,直接解析 xl/charts/chart*.xml,实现了对 Excel 图表元数据的精准提取,感兴趣的小伙伴可以了解下
    2026-01-01
  • 十条建议帮你提高Python编程效率

    十条建议帮你提高Python编程效率

    这篇文章主要为大家介绍了十条建议,可以帮你提高Python编程效率的10条,想要提升提高Python编程效率的朋友不要错过
    2016-02-02
  • Python使用random.shuffle()随机打乱字典排序

    Python使用random.shuffle()随机打乱字典排序

    本文主要介绍了Python使用random.shuffle()随机打乱字典排序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08

最新评论