18 What is the

    xiaoxiao2021-12-15  52

    What is the __dict__.__dict__attribute of a Python class?

    What is the __dict____dict__attribute of a Python class problem解释实例中不存在__dict__的情况__dict__不存储在实例上的原因总结code参考网址

    转载请标明出处(http://blog.csdn.net/lis_12/article/details/53519060)

    problem

    class Foo(object): pass >>>Foo.__dict__ dict_proxy({'__dict__': <attribute '__dict__' of 'Foo' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None}) >>>Foo.__dict__.__dict__ AttributeError: 'dictproxy' object has no attribute '__dict__' >>>Foo.__dict__['__dict__'] <attribute '__dict__' of 'Foo' objects>

    Foo.__dict__里面有'__dict__': <attribute '__dict__' of 'Foo' objects>属性,用Foo.__dict__.__dict__访问不到,用Foo.__dict__['__dict__']可以访问到,为什么呢?

    搜索结果:stackoverflow解释链接,本文也是基于stackoverflow的解释,另外本文不考虑没有__dict__属性的实例。为了更好的理解本文,建议学习描述符…

    解释

    ​ Foo.__dict__.__dict__和Foo.__dict__['__dict__']是不一样的。

    Foo.__dict__.__dict__ :根本就不存在Foo.__dict__['__dict__'] :用来存储Foo实例的__dict__属性。

    实例

    实例会创建一个单独的dict对象来存储实例的属性,实例的__dict__存储在实例对应的类上,即type(实例)上。

    instance.__dict__可以从type(instance).__dict__['__dict__']中获取;

    因为type(instance).__dict__['__dict__']为描述符,

    所以instance.__dict__ = type(instance).__dict__['__dict__'].__get__(instance,type(instance))

    t = Foo.__dict__['__dict__'] print '__get__' in dir(t) #True,说明Foo.__dict__['__dict__']是描述符 print type(t) #<type 'getset_descriptor'> f = Foo() print type(f.__dict__) #<type 'dict'> d = t.__get__(f,type(f)) #利用描述符对象获取实例的__dict__ print f.__dict__ is d #True,证明上述正确

    类,以类Foo为例,

    Foo的__dict__属性没有存储在Foo上,而是存储在Foo对应的类上,即type(Foo)上。对于type(Foo)来说,Foo为type(Foo)的实例。

    Foo.__dict__可以从type(Foo).__dict__['__dict__']中获取;

    因为type(Foo).__dict__['__dict__']为描述符,

    所以Foo.__dict__ = type(Foo).__dict__['__dict__'].__get__(Foo,type(Foo))

    t = type(Foo).__dict__['__dict__'] print '__get__' in dir(t) #True,说明type(Foo).__dict__['__dict__']是描述符 print type(t) #<type 'getset_descriptor'> print type(Foo.__dict__) #<type 'dictproxy'>,与实例的__dict__属性不同 d = t.__get__(Foo) print Foo.__dict__ == d #True,值相等 print Foo.__dict__ is d #False,虽然值相等,但地址不同,猜想...d应该是Foo.__dict__的拷贝,知道的大神求指导

    类的__dict__属性不同于实例的__dict__属性。类的__dict__属性是一个特殊代理对象(dictproxy),只不过这个对象伪装成了字典,并且class.__dict__不允许更改和替换。

    摘自官网的一句话:new-style classes use a dictproxy to prevent direct dictionary updates.

    class A(object): pass print A.__dict__ #{'__dict__': <attribute '__dict__' of 'A' objects>... print type(A.__dict__) #<type 'dictproxy'> #不能重写A.__dict__ A.__dict__ = 1 #AttributeError: attribute '__dict__' of 'type' objects is not writable

    实例中不存在__dict__的情况

    默认情况下,一个空的类有三个描述符,

    __dict__,存储实例属性;__weakref__;__doc__

    如果定义了__slots__,__dict__和__weakref__两个属性就没有了,__slots__中出现的变量名称将会以类属性的形式存在。

    class Foo(object): __slots__ = 'a','b' f = Foo() #print f.__dict__ #AttributeError: 'Foo' object has no attribute '__dict__' print Foo.__dict__ #{'a': <member 'a' of 'Foo' objects>, '__module__': '__main__', 'b': <member 'b' of 'Foo' objects>, '__slots__': ('a', 'b'), '__doc__': None}

    __dict__不存储在实例上的原因

    As it’s impossible for the __dict__ of instance to be stored in __dict__ of the instance, it is accessed through the descriptor protocol directly instead, and is stored in a special field in the instance.

    原因:

    The inconsistency that A.__dict__ is different from A.__dict__['__dict__'] is because the attribute __dict__ is, by exception, never looked up in vars(A), so what is true for it isn’t true for practically any other attribute you’d use. For example, A.__weakref__ is the same thing as A.__dict__['__weakref__']. If this inconsistency didn’t exist, using A.__dict__ would not work, and you’d have to always use vars(A) instead.

    总结

    以类Foo为例,Foo.attr与Foo.__dict__['attr']不相等的情况:

    Foo.__dict__ != Foo.__dict__['__dict__']

    因为__dict__属性是个例外,Foo.__dict__并没有存储在Foo上,而是存储在type(Foo)上 。

    Foo.__dict__ == type(Foo).__dict__['__dict__'].__get__(Foo)

    如果attr为自定义的描述符对象,Foo.attr != Foo.__dict__['attr']

    在属性访问时,如果被访问的属性为描述符,会自动调用描述符的__get__()方法,

    所以Foo.attr == Foo.__dict__['attr'].__get__(None,Foo)

    class d(object): def __get__(self,obj,type = None): return 1 class Foo(object): a = d() b = 1 def attr(self): pass '''attr为自定义方法,证明方法为描述符''' print '__get__' in dir(Foo.__dict__['attr']) #True print Foo.attr == Foo.__dict__['attr'] #False print Foo.attr == Foo.__dict__['attr'].__get__(None,Foo)#True '''自定义的描述符''' x = Foo.a y = Foo.__dict__['a'] print x == y #False print x == y.__get__(None,Foo) #True

    Foo.attr与Foo.__dict__['attr']相等的情况:

    Foo.attr == Foo.__dict__['attr'],attr不是__dict__和自定义描述符.

    print Foo.b == Foo.__dict__['b'] #True w = Foo.__dict__['__weakref__'] print '__get__' in dir(Foo.__weakref__) #True print Foo.__weakref__ == w #True,__weakref__不是自定义描述符 print Foo.__weakref__ == w.__get__(None,Foo) #True

    code

    class A(object): pass a = A() print 'type(a) = ',type(a) #type(a) = <class '__main__.A'> print 'type(A) = ',type(A) #type(A) = <type 'type'> print 'a.__dict__ = ',a.__dict__ #a.__dict__ = {} print 'A.__dict__ = ',A.__dict__ #{'__dict__': <attribute '__dict__' of 'A' objects>... #print 'type.__dict__ = ',type.__dict__,'\n' print 'type(a.__dict__) = ',type(a.__dict__) print 'type(A.__dict__) = ',type(A.__dict__) print 'type(type.__dict__) = ',type(type.__dict__),'\n' ''' result: type(a.__dict__) = <type 'dict'> type(A.__dict__) = <type 'dictproxy'> type(type.__dict__) = <type 'dictproxy'> ''' print "A.__dict__['__dict__'] = ",A.__dict__['__dict__'] print "type.__dict__['__dict__'] = ",type.__dict__['__dict__'],'\n' print "type(A.__dict__['__dict__']) = ",type(A.__dict__['__dict__']) print "type(type.__dict__['__dict__']) = ",type(type.__dict__['__dict__']),'\n' ''' result: A.__dict__['__dict__'] = <attribute '__dict__' of 'A' objects> type.__dict__['__dict__'] = <attribute '__dict__' of 'type' objects> type(A.__dict__['__dict__']) = <type 'getset_descriptor'> type(type.__dict__['__dict__']) = <type 'getset_descriptor'> ''' print a.__dict__ == A.__dict__['__dict__'].__get__(a) print a.__dict__ == A.__dict__['__dict__'].__get__(a,type(a)) print A.__dict__ == type(A).__getattribute__(A, '__dict__') print A.__dict__ == type(A).__dict__['__dict__'].__get__(A) print A.__dict__ == type(A).__dict__['__dict__'].__get__(A,type(A)) print a.__dict__ == A.__getattribute__(a, '__dict__') print a.__dict__ == type(A).__dict__['__dict__'].__get__(A)['__dict__'].__get__(a) #上述都为True

    参考网址

    http://stackoverflow.com/questions/4877290/what-is-the-dict-dict-attribute-of-a-python-classhttps://docs.python.org/2/library/functions.html?highlight=dictproxyhttp://stackoverflow.com/questions/25440694/whats-the-purpose-of-dictproxyhttp://blog.csdn.net/lis_12/article/details/53453665http://blog.csdn.net/lis_12/article/details/53511300
    转载请注明原文地址: https://ju.6miu.com/read-1000056.html

    最新回复(0)