文档章节

__getattr__和__getattribute__之间的区别

 技术盛宴
发布于 02/20 09:42
字数 1154
阅读 47
收藏 0

我试图了解何时使用__getattr____getattribute__ 。 提及__getattribute__文档适用于新型类。 什么是新型类?


#1楼

这只是基于Ned Batchelder的解释的示例

__getattr__示例:

class Foo(object):
    def __getattr__(self, attr):
        print "looking up", attr
        value = 42
        self.__dict__[attr] = value
        return value

f = Foo()
print f.x 
#output >>> looking up x 42

f.x = 3
print f.x 
#output >>> 3

print ('__getattr__ sets a default value if undefeined OR __getattr__ to define how to handle attributes that are not found')

如果在__getattribute__使用相同的示例,则会得到>>> RuntimeError: maximum recursion depth exceeded while calling a Python object


#2楼

新型类是(直接或间接)子类化“对象”的类。 除了__init__外,它们还具有__new__类方法,并且具有更合理的低级行为。

通常,您将需要覆盖__getattr__ (如果要覆盖其中的任何一个),否则您将很难在方法中支持“ self.foo”语法。

额外信息: http : //www.devx.com/opensource/Article/31482/0/page/4


#3楼

新样式类继承自object或另一个新样式类:

class SomeObject(object):
    pass

class SubObject(SomeObject):
    pass

旧式类不能:

class SomeObject:
    pass

这仅适用于Python 2-在Python 3中,以上所有内容都会创建新样式的类。

请参见9.类 (Python教程), NewClassVsClassicClass和Python中旧样式类和新样式类之间的区别是什么? 有关详细信息。


#4楼

__getattr____getattribute__之间的主要区别在于,只有在找不到常规方法的情况下才调用__getattr__ 。 这对于实现缺少属性的后备方法很有用,并且可能是您想要的两个之一。

在查看对象的实际属性之前,将调用__getattribute__ ,因此正确实现可能会很棘手。 您可以非常轻松地进行无限递归。

新样式类是从object派生的,旧样式类是Python 2.x中没有显式基类的类。 但是,在__getattr____getattribute__之间进行选择时,旧样式类与新样式类之间的区别并不是重要的区别。

您几乎可以肯定想要__getattr__


#5楼

让我们看一下__getattr____getattribute__魔术方法的一些简单示例。

__getattr__

每当您请求尚未定义的属性时,Python都会调用__getattr__方法。 在下面的示例中,我的Count类没有__getattr__方法。 现在主要是当我尝试同时访问obj1.myminobj1.mymax属性时,一切正常。 但是当我尝试访问obj1.mycurrent属性时obj1.mycurrent给了我AttributeError: 'Count' object has no attribute 'mycurrent'

class Count():
    def __init__(self,mymin,mymax):
        self.mymin=mymin
        self.mymax=mymax

obj1 = Count(1,10)
print(obj1.mymin)
print(obj1.mymax)
print(obj1.mycurrent)  --> AttributeError: 'Count' object has no attribute 'mycurrent'

现在,我的班Count具有__getattr__方法。 现在,当我尝试访问obj1.mycurrent属性时obj1.mycurrent返回我在__getattr__方法中实现的内容。 在我的示例中,每当我尝试调用不存在的属性时,python都会创建该属性并将其设置为整数值0。

class Count:
    def __init__(self,mymin,mymax):
        self.mymin=mymin
        self.mymax=mymax    

    def __getattr__(self, item):
        self.__dict__[item]=0
        return 0

obj1 = Count(1,10)
print(obj1.mymin)
print(obj1.mymax)
print(obj1.mycurrent1)

__getattribute__

现在让我们看一下__getattribute__方法。 如果您的类中具有__getattribute__方法,则python会为每个属性调用此方法,无论该属性是否存在。 那么为什么我们需要__getattribute__方法呢? 一个很好的理由是,您可以阻止访问属性并使它们更安全,如以下示例所示。

每当有人尝试访问以子字符串“ cur”开头的我的属性时,python都会引发AttributeError异常。 否则,它将返回该属性。

class Count:

    def __init__(self,mymin,mymax):
        self.mymin=mymin
        self.mymax=mymax
        self.current=None

    def __getattribute__(self, item):
        if item.startswith('cur'):
            raise AttributeError
        return object.__getattribute__(self,item) 
        # or you can use ---return super().__getattribute__(item)

obj1 = Count(1,10)
print(obj1.mymin)
print(obj1.mymax)
print(obj1.current)

重要说明:为了避免__getattribute__方法中的无限递归,其实现应始终调用具有相同名称的基类方法以访问其所需的任何属性。 例如: object.__getattribute__(self, name)super().__getattribute__(item)而不是self.__dict__[item]

重要

如果您的类同时包含getattrgetattribute魔术方法,则首先调用__getattribute__ 。 但是,如果__getattribute__引发AttributeError异常,则将忽略该异常并调用__getattr__方法。 请参见以下示例:

class Count(object):

    def __init__(self,mymin,mymax):
        self.mymin=mymin
        self.mymax=mymax
        self.current=None

    def __getattr__(self, item):
            self.__dict__[item]=0
            return 0

    def __getattribute__(self, item):
        if item.startswith('cur'):
            raise AttributeError
        return object.__getattribute__(self,item)
        # or you can use ---return super().__getattribute__(item)
        # note this class subclass object

obj1 = Count(1,10)
print(obj1.mymin)
print(obj1.mymax)
print(obj1.current)

本文转载自:https://stackoom.com/question/DkmD/getattr-和-getattribute-之间的区别

粉丝 0
博文 1589
码字总数 0
作品 0
深圳
高级程序员
私信 提问
加载中

评论(0)

__get__,__getattr__和__getattribute方法

get,getattr和getattribute都是访问属性的方法,但不太相同。 object.getattr(self, name) 当一般位置找不到attribute的时候,会调用getattr,返回一个值或AttributeError异常。 object.get...

阿帆提
2016/11/16
26
0
Python object类中的特殊方法代码讲解

在本篇文章里小编给各位整理了关于Python object类中的特殊方法代码讲解,需要的朋友们可以参考下。 python版本:3.8 二、常用特殊方法解释 1.getattribute方法 1)什么时候被调用 这个特殊方...

程序员aki
前天
0
0
Python - __getattr__() 和 __getattribute__() 方法的区别

python 再访问属性的方法上定义了getattr() 和 getattribute() 2种方法,其区别非常细微,但非常重要。 如果某个类定义了 方法,在 每次引用属性或方法名称时 Python 都调用它(特殊方法名称...

索隆
2012/05/13
287
0
python:__getattr__() 和 __getattribute__()

关于getattr object.getattr(self, name) Called when an attribute lookup has not found the attribute in the usual places (i.e. it is not an instance attribute nor is it found in t......

樂天
2013/11/12
2K
0
python __setattr__、__getattr__、__getattribute__全面详解

一、属性引用函数 hasattr(obj,name[,default]) getattr(obj,name) setattr(obj,name,value) delattr(obj,name) 二、属性引用重载 def setattr(self,key,value):   1.拦截所有属性的赋值语......

智能先行者
2017/10/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

常用网络安全命令

常用网络安全命令 0. 首先打开cmd win+r 1. ipconfig命令 主要功能:显示本地主机IP地址、子网掩码、默认网关、MAC地址等 C:\> ipconfig/all 2.ping命令 主要功能:目标主机的可达性、名称、...

osc_6n4iy0i5
9分钟前
18
0
element-ui 响应式布局-栅格布局

要注意的问题 xs sm md lg xl五个尺寸的默认值均为24,意味着,任何一个尺寸属性不设置,则该尺寸下响应式宽度为24,这与bootstrap不同 尺寸属性可以设为0,则该el-col不显示 不论尺寸属性设...

osc_7ehwx8hw
11分钟前
16
0
初识二进制与软件破解

文章目录 简介 环境和工具 知识铺垫 实验 总结 简介 实验的思路来自《0day安全:软件漏洞技术分析》第一章。此次实验的内容为如何破解一个简单的密码验证功能的exe文件。通过此次实验可以大体...

osc_z3ivsxnp
12分钟前
15
0
【Q&A干货分享】敲重点,企业必须关注的等保灵魂20问

随着国内疫情防控取得积极成效,企业逐步复工复产,等保合规也重新提上重要日程。自去年12月1日,我国《信息安全等级保护管理办法》正式进入2.0时代,但目前传统的等保安全产品,市面上产品繁...

osc_1ajf1srl
13分钟前
6
0
大众点评字体反爬解析

有关大众点评字体反爬的解析 前几天收到一条私信是有关大众点评的字体反爬的问题,经过分析来此跟大家分享一下解决这个反爬的方法。 1.我们随便打开大众点评一个商家的网页,如下图 2.右键点...

osc_cgllnrkd
14分钟前
16
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部