<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                探究更多的類屬性,在一些初學者的教程中,一般很少見。我之所以要在這里也將這部分奉獻出來,就是因為本教程是“From Beginner to Master”。當然,不是學習了類的更多屬性就能達到Master水平,但是這是通往Master的一步,雖然在初級應用中,本節乃至于后面關于類的屬性用的不很多,但是,這一步邁出去,你就會在實踐中有一個印象,以后需要用到了,知道有這一步,會對項目有幫助的。俗話說“藝不壓身”。 ## [](https://github.com/qiwsir/StarterLearningPython/blob/master/212.md#__dict__)`__dict__` 前面已經學習過有關類屬性和實例屬性的內容,并且做了區分,如果忘記了可以回頭參閱[《類(3)》](https://github.com/qiwsir/StarterLearningPython/blob/master/208.md)中的“類屬性和實例屬性”部分。有一個結論,是一定要熟悉的,那就是可以通過`object.attribute`的方式訪問對象的屬性。 如果接著那部分內容,讀者是否思考過一個問題:類或者實例屬性,在python中是怎么存儲的?或者為什么修改或者增加、刪除屬性,我們能不能控制這些屬性? ~~~ >>> class A(object): ... pass ... >>> a = A() >>> dir(a) ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] >>> dir(A) ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] ~~~ 用`dir()`來查看一下,發現不管是類還是實例,都有很多屬性,這在前面已經反復出現,有點見怪不怪了。不過,這里我們要看一個屬性:`__dict__`,因為它是一個保存秘密的東西:對象的屬性。 ~~~ >>> class Spring(object): ... season = "the spring of class" ... >>> Spring.__dict__ dict_proxy({'__dict__': <attribute '__dict__' of 'Spring' objects>, 'season': 'the spring of class', '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Spring' objects>, '__doc__': None}) ~~~ 為了便于觀察,我將上面的顯示結果進行了換行,每個鍵值對一行。 對于類Spring的`__dict__`屬性,可以發現,有一個鍵`'season'`,這就是這個類的屬性;其值就是類屬性的數據。 ~~~ >>> Spring.__dict__['season'] 'the spring of class' >>> Spring.season 'the spring of class' ~~~ 用這兩種方式都能得到類屬性的值。或者說`Spring.__dict__['season']`就是訪問類屬性。下面將這個類實例化,再看看它的實例屬性: ~~~ >>> s = Spring() >>> s.__dict__ {} ~~~ 實例屬性的`__dict__`是空的。有點奇怪?不奇怪,接著看: ~~~ >>> s.season 'the spring of class' ~~~ 這個其實是指向了類屬性中的`Spring.season`,至此,我們其實還沒有建立任何實例屬性呢。下面就建立一個實例屬性: ~~~ >>> s.season = "the spring of instance" >>> s.__dict__ {'season': 'the spring of instance'} ~~~ 這樣,實例屬性里面就不空了。這時候建立的實例屬性和上面的那個`s.season`只不過重名,并且把它“遮蓋”了。這句好是不是熟悉?因為在講述“實例屬性”和“類屬性”的時候就提到了。現在讀者肯定理解更深入了。 ~~~ >>> s.__dict__['season'] 'the spring of instance' >>> s.season 'the spring of instance' ~~~ 此時,那個類屬性如何?我們看看: ~~~ >>> Spring.__dict__['season'] 'the spring of class' >>> Spring.__dict__ dict_proxy({'__dict__': <attribute '__dict__' of 'Spring' objects>, 'season': 'the spring of class', '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Spring' objects>, '__doc__': None}) >>> Spring.season 'the spring of class' ~~~ Spring的類屬性沒有受到實例屬性的影響。 按照前面的講述類屬性和實例熟悉的操作,如果這時候將前面的實例屬性刪除,會不會回到實例屬性`s.__dict__`為空呢? ~~~ >>> del s.season >>> s.__dict__ {} >>> s.season 'the spring of class' ~~~ 果然打回原形。 當然,你可以定義其它名稱的實例屬性,它一樣被存儲到`__dict__`屬性里面: ~~~ >>> s.lang = "python" >>> s.__dict__ {'lang': 'python'} >>> s.__dict__['lang'] 'python' ~~~ 誠然,這樣做僅僅是更改了實例的`__dict__`內容,對`Spring.__dict__`無任何影響,也就是說通過`Spring.lang`或者`Spring.__dict__['lang']`是得不到上述結果的。 ~~~ >>> Spring.lang Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: type object 'Spring' has no attribute 'lang' >>> Spring.__dict__['lang'] Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'lang' ~~~ 那么,如果這樣操作,會怎樣呢? ~~~ >>> Spring.flower = "peach" >>> Spring.__dict__ dict_proxy({'__module__': '__main__', 'flower': 'peach', 'season': 'the spring of class', '__dict__': <attribute '__dict__' of 'Spring' objects>, '__weakref__': <attribute '__weakref__' of 'Spring' objects>, '__doc__': None}) >>> Spring.__dict__['flower'] 'peach' ~~~ 在類的`__dict__`被更改了,類屬性中增加了一個'flower'屬性。但是,實例的`__dict__`中如何? ~~~ >>> s.__dict__ {'lang': 'python'} ~~~ 沒有被修改。我也是這么想的,哈哈。你此前這這么覺得嗎?然而,還能這樣: ~~~ >>> s.flower 'peach' ~~~ 這個讀者是否能解釋?其實又回到了前面第一個出現`s.season`上面了。 通過上面探討,是不是基本理解了實例和類的`__dict__`,并且也看到了屬性的變化特點。特別是,這些屬性都是可以動態變化的,就是你可以隨時修改和增刪。 屬性如此,方法呢?下面就看看方法(類中的函數)。 ~~~ >>> class Spring(object): ... def tree(self, x): ... self.x = x ... return self.x ... >>> Spring.__dict__ dict_proxy({'__dict__': <attribute '__dict__' of 'Spring' objects>, '__weakref__': <attribute '__weakref__' of 'Spring' objects>, '__module__': '__main__', 'tree': <function tree at 0xb748fdf4>, '__doc__': None}) >>> Spring.__dict__['tree'] <function tree at 0xb748fdf4> ~~~ 結果跟前面討論屬性差不多,方法`tree`也在`__dict__`里面呢。 ~~~ >>> t = Spring() >>> t.__dict__ {} ~~~ 又跟前面一樣。雖然建立了實例,但是在實例的`__dict__`中沒有方法。接下來,執行: ~~~ >>> t.tree("xiangzhangshu") 'xiangzhangshu' ~~~ 在[類(3)](https://github.com/qiwsir/StarterLearningPython/blob/master/208.md)中有一部分內容闡述“數據流轉”,其中有一張圖,其中非常明確顯示出,當用上面方式執行方法的時候,實例`t`與`self`建立了對應關系,兩者是一個外一個內。在方法中`self.x = x`,將x的值給了self.x,也就是實例應該擁有了這么一個屬性。 ~~~ >>> t.__dict__ {'x': 'xiangzhangshu'} ~~~ 果然如此。這也印證了實例`t`和`self`的關系,即實例方法(`t.tree('xiangzhangshu')`)的第一個參數(self,但沒有寫出來)綁定實例t,透過self.x來設定值,即給`t.__dict__`添加屬性值。 換一個角度: ~~~ >>> class Spring(object): ... def tree(self, x): ... return x ... ~~~ 這回方法中沒有將x賦值給self的屬性,而是直接return,結果是: ~~~ >>> s = Spring() >>> s.tree("liushu") 'liushu' >>> s.__dict__ {} ~~~ 是不是理解更深入了? 現在需要對python中一個觀點:“一切皆對象”,再深入領悟。以上不管是類還是的實例的屬性和方法,都是符合`object.attribute`格式,并且屬性類似。 當你看到這里的時候,要么明白了類和實例的`__dict__`的特點,要么就糊涂了。糊涂也不要緊,再將上面的重復一遍,特別是自己要敲一敲有關代碼。(建議一個最好的方法:用兩個顯示器,一個顯示器看本教程,另外一個顯示器敲代碼。事半功倍的效果。) 需要說明,我們對`__dict__`的探討還留有一個尾巴:屬性搜索路徑。這個留在后面講述。 不管是類還是實例,其屬性都能隨意增加。這點在有時候不是一件好事情,或許在某些時候你不希望別人增加屬性。有辦法嗎?當然有,請繼續學習。 ## [](https://github.com/qiwsir/StarterLearningPython/blob/master/212.md#__slots__)`__slots__` 首先聲明,`__slots__`能夠限制屬性的定義,但是這不是它存在終極目標,它存在的終極目標更應該是一個在編程中非常重要的方面:**優化內存使用。** ~~~ >>> class Spring(object): ... __slots__ = ("tree", "flower") ... >>> dir(Spring) ['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'flower', 'tree'] ~~~ 仔細看看`dir()`的結果,還有`__dict__`屬性嗎?沒有了,的確沒有了。也就是說`__slots__`把`__dict__`擠出去了,它進入了類的屬性。 ~~~ >>> Spring.__slots__ ('tree', 'flower') ~~~ 這里可以看出,類Spring有且僅有兩個屬性。 ~~~ >>> t = Spring() >>> t.__slots__ ('tree', 'flower') ~~~ 實例化之后,實例的`__slots__`與類的完全一樣,這跟前面的`__dict__`大不一樣了。 ~~~ >>> Spring.tree = "liushu" ~~~ 通過類,先賦予一個屬性值。然后,檢驗一下實例能否修改這個屬性: ~~~ >>> t.tree = "guangyulan" Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Spring' object attribute 'tree' is read-only ~~~ 看來,我們的意圖不能達成,報錯信息中顯示,`tree`這個屬性是只讀的,不能修改了。 ~~~ >>> t.tree 'liushu' ~~~ 因為前面已經通過類給這個屬性賦值了。不能用實例屬性來修改。只能: ~~~ >>> Spring.tree = "guangyulan" >>> t.tree 'guangyulan' ~~~ 用類屬性修改。但是對于沒有用類屬性賦值的,可以通過實例屬性: ~~~ >>> t.flower = "haitanghua" >>> t.flower 'haitanghua' ~~~ 但此時: ~~~ >>> Spring.flower <member 'flower' of 'Spring' objects> ~~~ 實例屬性的值并沒有傳回到類屬性,你也可以理解為新建立了一個同名的實例屬性。如果再給類屬性賦值,那么就會這樣了: ~~~ >>> Spring.flower = "ziteng" >>> t.flower 'ziteng' ~~~ 當然,此時在給`t.flower`重新賦值,就會爆出跟前面一樣的錯誤了。 ~~~ >>> t.water = "green" Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Spring' object has no attribute 'water' ~~~ 這里試圖給實例新增一個屬性,也失敗了。 看來`__slots__`已經把實例屬性牢牢地管控了起來,但更本質是的是優化了內存。誠然,這種優化會在大量的實例時候顯出效果。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看