成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Some question about python design

jaysun / 2767人閱讀

摘要:問題起源在中對于某些屬性是只讀的,比如對于。這會導致一些令人費解的錯誤。首先,和是不同的,不存在,是指的實例擁有的屬性,它是一個描述器,調用它會返回實例的屬性。的調用會按照以下順序會按照同樣順序,但是很明顯會跳過的訪問。

0x01 Q-1: why types (str, int, dict, ...) __dict__ attribute is dict_proxy object in python2 (or mappingproxy object in python3.3+) ?
>>> str.__dict__
dict_proxy({"__add__": ,
            "__contains__": ,
            .....
            "zfill": })
>>> type(str.__dict__)

>>> s = "abc"
>>> s.__dict__
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: "str" object has no attribute "__dict__"
問題起源

在 Python 中對于某些 object __dict__ 屬性是只讀的,比如對于 type object。然而,在 Python2.5-2.6 之前,還是有一些一般性方法可以獲取和改變 __dict__ 屬性的(without hacking with
gc.get_referrents(), that is)。這會導致一些令人費解的錯誤。

dictproxy 是為了用于保證 class.__dict__ 的 keys 必須是 strings, proxy 的機制防止了對于 class.__dict__ 的寫入操作, 因此只有 setattr() 可以被用于添加屬性, class.__setattr__ 的實現(xiàn)確保了 keys-must-be-strings 的限制.

如果我們不使用一些 proxy 的機制,那么 __dict__,class.__dict__ 就可以被寫入了。如果可以寫入,也就可以被刪除,而 class.__dict__ 中的屬性被刪除可能會導致解釋器崩潰。

The __dict__ attribute of some objects is read-only,
e.g. for type objects. However, there is a generic

way to still access and modify it (without hacking with
gc.get_referrents(), that is). This can lead to
obscure crashes. Attached is an example that shows
a potential "problem" involving putting strange keys
in the __dict__ of a type.

This is probably very minor anyway. If we wanted to

fix this, we would need a __dict__ descriptor that
looks more cleverly at the object to which it is
applied.

BTW the first person who understand why the attached

program crashes gets a free coffee.

------- [Armin Rigo] Bypassing dict readonlyness [Python2.5-2.6]

Q-2: why built-in class instances don"t have __dict__ attribute ?

Instances of types defined in C don"t have a __dict__ attribute by default.

Q-3: what is the __dict__["__dict__"] attribute of a Python class?
>>> class A(object):
        x = "1"
        def __init__(self):
            self.x = "2"

>>> a = A()
>>> a.__dict__
{"x": "2"}
>>> type(a.__dict__)
dict
>>> A.__dict__
dict_proxy({"__dict__": ,
            "__doc__": None,
            "__init__": ,
            "__module__": "__main__",
            "__weakref__": ,
            "x": "1"})
>>> type(A.__dict__)
dict_proxy
>>> A.__dict__["__dict__"]

>>> type(A.__dict__["__dict__"])
getset_descriptor
>>> isinstance(A.__dict__["__dict__"], types.GetSetDescriptorType)
True
>>> A.__dict__["__dict__"].__get__(a, A)
{"x": "2"}
>>> a.__dict__
{"x": "2"}

首先,A.__dict__.__dict__A.__dict__["__dict__"] 是不同的,A.__dict__.__dict__ 不存在,A.__dict__["__dict__"] 是指 class 的實例擁有的 __dict__ 屬性,它是一個描述器,調用它會返回實例的 __dict__ 屬性。簡單來說,因為一個實例的 __dict__ 屬性不能(why?)保存在實例的 __dict__ 中,所以需要通過 class 中的一個 descriptor 來調用。(因為 python 是動態(tài)語言嘛,A.__dict__["__dict__"] 是一個 GetsetDescriptor,所以實例的屬性是有能力增加的)

對于 class A 的實例 a ,訪問 a.__dict__ 時的背后是通過 A.__dict__["__dict__"] 實現(xiàn)的(vars(A)["__dict__"]

對于 class A,訪問 A.__dict__ 理論上 是通過 type.__dict__["__dict__"] 實現(xiàn)的(vars(type)["__dict__"]

完整解釋:

class 和實例訪問屬性都是通過屬性操作符 (class or metaclass"s __getattribute__) 和 __dict__ 屬性/協(xié)議實現(xiàn)的。

對于一般的實例對象,__dict__ 會返回一個保存包含所有實例屬性的獨立的 dict 實例對象,對 __getattribute__ 的調用首先會訪問這個 dict,并獲取相應的實例屬性 (這個調用會在通過描述器協(xié)議訪問 class 屬性之前,也會在調用 __getattr__ 之前)。class 里定義的 __dict__ 描述器實現(xiàn)了對這個 dict 的訪問。

x.name 的調用會按照以下順序: x.__dict__["name"], type(x).name.__get__(x, type(x)), type(x).name

x.__dict__ 會按照同樣順序,但是很明顯會跳過 x.__dict__["name"] 的訪問。

因為 x.__dict__ 不能保存在 x.__dict__["__dict__"] 中,對于 x.__dict__ 的訪問就會用描述器協(xié)議實現(xiàn),x.__dict__ 的值就會保存在實例中的一個特殊字段里。

對于 class 也會面臨相同的情況,雖然 class.__dict__ 是一個偽裝成 dict 的特殊的 proxy 對象,class.__dict__ 也不允許你對它進行
修改或替換行為。這個特殊的 proxy 對象允許你,獲取那些定義在 class 而不是 class 的基類中的的屬性。

默認情況下,vars(cls) 對于一個空類型,返回的對象包含三個描述器,__dict__ 用于保存實例中的屬性,__weakref__ 是用于 weakref 模塊的內(nèi)部邏輯,__doc__ 是用于 class 的 docstring。前兩個描述器可能會因為定義了 __slots__ 而消失,沒有 __dict__ and __weakref__ 屬性,反而會有每一個定義在 __slots__ 的屬性。此時,實例的屬性不會保存在 dict 中,訪問屬性將會通過相應的描述器實現(xiàn)。

refs: What is the dict__.__dict attribute of a Python class?

Q-4: what"s the order of access instance"s attribute ?
# -*- encoding: utf -*-


class RevealAccess(object):
    """A data descriptor that sets and returns values
       normally and prints a message logging their access.
    """
    def __init__(self, initval=None, name="var"):
        self.val = initval
        self.name = name

    def __get__(self, obj, objtype):
        print("Retrieving", self.name, self.val)
        return self.val

    def __set__(self, obj, val):
        print("Updating", self.name, self.val)
        self.val = val


class Base(object):
    attr_1 = RevealAccess(10, "var "x"")

    def __init__(self):
        self.attr_2 = RevealAccess(10, "var "x"")

    def __getattribute__(self, *args, **kwargs):
        print("__getattribute__", args, kwargs)
        return super(Base, self).__getattribute__(*args, **kwargs)

    def __getattr__(self, *args, **kwargs):
        print("__getattr__", args, kwargs)
        try:
            origin = super(Base, self).__getattr__(*args, **kwargs)
            return origin
        except AttributeError as e:
            return "not found"


def main():
    b = Base()
    print("*********** start get b.attr_1 ***********")
    print(b.attr_1)
    print("*********** start get b.attr_2 ***********")
    print(b.attr_2)
    print("*********** start get b.attr_3 ***********")
    print(b.attr_3)

if __name__ == "__main__":
    main()

Output:
*********** start get b.attr_1 ***********
("__getattribute__", ("attr_1",), {})
("Retrieving", "var "x"", 10)
10
*********** start get b.attr_2 ***********
("__getattribute__", ("attr_2",), {})
<__main__.RevealAccess object at 0x100b1abd0>
*********** start get b.attr_3 ***********
("__getattribute__", ("attr_3",), {})
("__getattr__", ("attr_3",), {})
not found

Refs:

How Does Attribute Access Work?

Python: Difference between class and instance attributes

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://m.hztianpu.com/yun/40676.html

相關文章

  • Pythonic “Data Science” Specialization

    摘要:溫習統(tǒng)計學的知識為更深層次的學習做準備在的演講中說就是我們理解但不知道另外的是如何的我在臺下想對于那可以理解的我好像都只懂了參考標準高效的流程課程用的是我不想再學一門類似的語言了我會找出相對應的和的來源流程什么是干凈的一個變 Why The Data Science Specialization 溫習統(tǒng)計學的知識, 為更深層次的學習做準備 Andrew Ng 在 2015 GTC ...

    jasperyang 評論0 收藏0
  • 2018 AI、機器學習、深度學習與 Tensorflow 相關優(yōu)秀書籍、課程、示例鏈接集錦

    摘要:機器學習深度學習與自然語言處理領域推薦的書籍列表人工智能深度學習與相關書籍課程示例列表是筆者系列的一部分對于其他的資料集錦模型開源工具與框架請參考。 showImg(https://segmentfault.com/img/remote/1460000014946199); DataScienceAI Book Links | 機器學習、深度學習與自然語言處理領域推薦的書籍列表 sho...

    wenshi11019 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<