为了账号安全,请及时绑定邮箱和手机立即绑定

_getattr_vs_getAttribute_

_getattr_vs_getAttribute_

慕姐4208626 2019-07-16 14:35:05
_getattr_vs_getAttribute_我想弄清楚什么时候该用__getattr__或__getattribute__..这个文献资料提及__getattribute__适用于新样式的类。什么是新类型的课程?
查看完整描述

3 回答

?
Helenr

TA贡献1780条经验 获得超4个赞

两个主要的区别__getattr____getattribute__那是__getattr__只有在没有按照通常的方式找到属性时才调用。它有利于实现丢失属性的回退,而且可能是您想要的两个属性中的一个。

__getattribute__在查看对象上的实际属性之前调用,因此要正确实现可能很困难。您可以很容易地在无限递归中结束。

新样式类派生自object,旧式类是Python2.x中没有显式基类的类。但是,在选择新旧类时,区分旧类和新类并不是重要的区别。__getattr____getattribute__.

你几乎肯定想__getattr__.


查看完整回答
反对 回复 2019-07-16
?
忽然笑

TA贡献1806条经验 获得超5个赞

让我们看看这两个方面的一些简单示例。__getattr____getattribute__神奇的方法。

__getattr__

Python会调用__getattr__方法,只要请求尚未定义的属性。在下面的示例中,我的类数数__getattr__方法。现在,主要是当我试图访问两个obj1.myminobj1.mymax属性一切都很好。但当我试图进入obj1.mycurrent属性-Python给了我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'

现在我的课数数__getattr__方法。现在当我试图访问obj1.mycurrent属性-python返回我在__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 0obj1 = 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]

重要

如果您的类同时包含两个盖塔getAttribute魔法方法__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 objectobj1 = Count(1,10)print(obj1.mymin)print(obj1.mymax)print(obj1.current)


查看完整回答
反对 回复 2019-07-16
?
牧羊人nacy

TA贡献1862条经验 获得超7个赞

__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 42f.x = 3print f.x 
#output >>> 3print ('__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


查看完整回答
反对 回复 2019-07-16
  • 3 回答
  • 0 关注
  • 438 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信