python類內init外聲明的屬性與init內聲明的對象屬性的訪問和操作區別


python類內init外聲明的屬性與init內聲明的對象屬性的訪問和操作區別(面試題) 

 

 1.在ipython中輸入以下代碼,其輸出會是什么?

In [1]: class ClassOut:
   ...:     out_mem = 'out_mem'
   ...:     print out_mem
   ...:     def __init__(self):
   ...:         inner_mem = 'inner_mem'
   ...:         self.inner_mem = 'self.inner_mem'
   ...:         self._inner_mem = 'self._inner_mem'
   ...:         self.out_mem = 'self.out_mem' 
   ...:     


In [2]: out = ClassOut()

In [3]: out.out_mem


In [4]: out._inner_mem


In [5]: out.inner_mem


In [6]: class ClassOut:
   ...:     out_mem = 'out_mem'
   ...:     print out_mem
   ...:     def __init__(self):
   ...:         inner_mem = 'inner_mem'
   ...:         self.inner_mem = 'self.inner_mem'
   ...:         self._inner_mem = 'self._inner_mem'
   ...:         self.out_mem1 = 'self.out_mem1'
   ...:         
out_mem

In [7]: out = ClassOut()

In [8]: out.out_mem


In [9]: ClassOut.out_mem


In [10]: ClassOut.out_mem1

In [11]: out._inner_mem


In [12]: out.out_mem = 'out_mem modified by object'

In [13]: ClassOut.out_mem


In [14]: out.out_mem


In [15]: out.new_mem = 'clas'

In [16]: out.new_mem


In [17]: o = ClassOut()

In [18]: o.out_mem


In [19]: ClassOut.out_mem


In [20]: ClassOut.out_mem = 'out_mem modified by Class'

In [21]: o.out_mem

 

 

 考察:

1. python解釋器處理解釋class

2. 類的初始化定義方法

3. 類的__init__方法 與 class object成員定義, class instance成員的定義

4. 類定義成員時的命名約定

5. class object  與 class instance的區別

6. class object 與 class instance在處理缺失成員訪問時查詢域優先級的區別

7. class 定義 __private_mem 不被外部發現的元嬰? (被重命名為_[class_name]__private_mem)!!!詳見如下代碼!

 

In [48]: class ClassOut:

    ...: out_mem = 'out_mem'

    ...: print out_mem

    ...: def __init__(self):

    ...: inner_mem = 'inner_mem'

    ...: self.inner_mem = 'self.inner_mem'

    ...: self._inner_mem = 'self._inner_mem'

    ...: self.out_mem1 = 'self.out_mem1'

    ...: self.__private_mem = 'self.__private_mem'

    ...:

out_mem

 

In [49]: no = ClassOut()

 

In [50]: no.__private_mem

---------------------------------------------------------------------------

AttributeError Traceback (most recent call last)

<ipython-input-50-36dd351a1b65> in <module>()

----> 1no.__private_mem

 

AttributeError: ClassOut instance has no attribute '__private_mem'

 

In [51]: no._ClassOut__private_mem

Out[51]: 'self.__private_mem'

 

 

 

 

 

8.1. 不能直接給對象設置屬性?

>>> obj = object()
>>> obj.name = "whatever"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'name'

但是為什么這樣就可以呢:

>>> class Object(object):pass
...
>>> Obj = Object()
>>> Obj.name = "whatever"
>>> Obj.name
'whatever'
>>>

答: 現在你給第二個代碼塊中的Object加上屬性 __slots__ 試試:

>>> class Object(object):
...     __slots__ = {}
...
>>> Obj = Object()
>>> Obj.name = "whatever"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Object' object has no attribute 'name'

會發現拋出了同樣的異常。 object 、 list 、 dict 等內置函數都如此。

擁有 __slots__ 屬性的類在實例化對象時不會自動分配 __dict__ ,而obj.attr 即 obj.__dict__['attr'], 所以會引起 AttributeError

對於擁有 __slots__ 屬性的類的實例 Obj 來說,只能對 Obj 設置__slots__ 中有的屬性:

>>> class Object(object):
...     __slots__ = {"a","b"}
...
>>> Obj = Object()
>>> Obj.a = 1
>>> Obj.a
1
>>> Obj.c = 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Object' object has no attribute 'c'

詳細見 Python-slots-doc


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM