教程簡介 Microsoft Dynamics CRM初學者教程 - 從簡單和簡單的步驟學習Microsoft Dynamics CRM,從基本到高級概念,包括基本概念到高級概念,包括概述,環境,功能模塊,實體和記錄,欄位,表單,搜索,Web資源,JScript Web資源,HTML Web資源,x ...
6.3 類屬性和對象屬性
在類定義中,屬性按照歸屬分為對象屬性、類屬性。按照調用的私密性分為一般屬性和私有屬性。
6.3.1 類屬性和對象屬性
對象屬性是最常用到的一種屬性。即使我們對上面的類:MyClass1實例化了一個mc的對象,mc對象也不能進行有實質的操作。因為mc對象的類:MyClass1中既沒有定義屬性也沒有定義方法。
在定義類時還能定義類屬性。接下來我們創建一個類:MyClass2,並添加一個類屬性:class_attr和對象屬性:obj_attr。然後再通過該類實例化一個對象mc。再通過不同的方式訪問類屬性和對象屬性,以便掌握類屬性和對象屬性的區別。代碼如下:
class MyClass2:
class_attr = 'ca'
def __init__(self):
self.obj_attr = 'oa'
mc = MyClass2()
print('通過對象訪問類屬性', mc.class_attr)
print('通過對象訪問對象屬性', mc.obj_attr)
print('通過類訪問類屬性', MyClass2.class_attr)
print('通過類訪問對象屬性', MyClass2.obj_attr)
通過對象訪問類屬性 ca
通過對象訪問對象屬性 oa
通過類訪問類屬性 ca
Traceback (most recent call last):
File "E:\BaiduNetdiskWorkspace\FrbPythonFiles\study\面向對象\類的私有屬性.py", line 12, in
print('通過類訪問對象屬性', MyClass2.obj_attr)
AttributeError: type object 'MyClass2' has no attribute 'obj_attr'
代碼解釋:
def __init__(self):
:表示創建一個類的構造函數,所謂構造函數,就是在類的實例化時會自動執行的方法。在Python類定義時,有一些是比較特殊的方法,這種方法的方法名一般以雙__
開始和結尾,在Python類中有著特別的意義。基於此,我們一般在類中定義方法時,方法名最好不要以__
開始。類一旦進行實例化後,就會執行__init__
這個構造方法進行初始化,一般這裡會進行屬性的初始化綁定和一些其他初始化動作。
mc = MyClass2()
:對MyClass2類的實例化,實例化後的對象就是mc
。接下來就可以通過mc來進行操作了。
self.obj_attr = 'oa':進行對象屬性的值綁定。這裡的self代表的就是實例化後的對象自己。
class_attr = 'ca':類屬性的賦值,類屬性賦值在類定義後就會生效,不需要實例化成對象。
通過對象名.屬性、類名.屬性就可以獲取到相應的屬性了。
通過上面的代碼可以看到,通過對象是可以正常訪問到對象屬性的,通過類可以訪問到類屬性,但是不能訪問到對象屬性。
對象或類對於屬性的訪問如下:
對象或類 | 對象屬性 | 類屬性 |
---|---|---|
對象 | √ | √ |
類 | × | √ |
接著我們來看是否能夠對屬性進行修改:
class Person:
age = 18
def __init__(self):
self.name = '張三'
self.gender = '男'
zhangsan = Person()
print('通過對象修改對象一般屬性', '+' * 30)
print(zhangsan.gender)
zhangsan.gender = '女'
print(zhangsan.gender)
print('通過對象修改類一般屬性', '+' * 30)
print(zhangsan.age)
zhangsan.age = 30
print(zhangsan.age)
print(Person.age)
print('通過類修改類一般屬性', '+' * 30)
print(Person.age)
Person.age = 25
print(Person.age)
print(zhangsan.age)
通過對象修改對象一般屬性 ++++++++++++++++++++++++++++++
男
女
通過對象修改類一般屬性 ++++++++++++++++++++++++++++++
18
30
18
通過類修改類一般屬性 ++++++++++++++++++++++++++++++
18
25
30
通過上面的代碼可以看到,無論是對象還是類,對於能夠訪問到的屬性就可以進行修改。
但是對象修改類屬性後,通過類調用的屬性不變。而如果是通過類修改類屬性後,對象調用的類屬性也不變。也就是說,對於類屬性,對象修改後不會影響到類,類修改後也不會影響到對象。
對象或類對於屬性的修改如下:
對象或類 | 對象屬性 | 類屬性 |
---|---|---|
對象 | √ | √ |
類 | × | √ |
6.3.2 一般屬性和私有屬性
平常定義類時,直接定義的都是一般屬性,就是可以通過對象名.屬性、類名.屬性直接調用到的。如上面例子中的:mc.class_attr和MyClass2.class_attr。
如果有些屬性名開發者不想讓其它開發人員調用時,則可以創建以雙__
開頭的屬性名,這種屬性名稱為私有屬性,在對象、類進行屬性調用時,則不能通過簡單的x.屬性名
的方式調用對象的屬性。
class Person:
__age = 18
def __init__(self):
self.name = '張三'
self.__gender = '男'
zhangsan = Person()
print(zhangsan.__gender)
在上面的定義中,通過self.__gender定義了一個私有屬性,直接運行上面的命令後會報錯,報錯如下:
Traceback (most recent call last):
File "E:\BaiduNetdiskWorkspace\FrbPythonFiles\study\面向對象\創建類.py", line 17, in
print(zhangsan.__gender)
AttributeError: 'Person' object has no attribute '__gender'
當然,在Python中沒有真正的私有屬性,通過__
開頭命名的屬性,在Python類中只是被自動修改了名稱而已。我們可以通過print(dir(zhangsan))
查看到zhangsan這個對象中所有的屬性和方法:
['_Person__age', '_Person__gender', 'class', 'delattr', 'dict', 'dir', 'doc', 'eq', 'format', 'ge', 'getattribute', 'gt', 'hash', 'init', 'init_subclass', 'le', 'lt', 'module', 'ne', 'new', 'reduce', 'reduce_ex', 'repr', 'setattr', 'sizeof', 'str', 'subclasshook', 'weakref']
我們看到,輸出的結果中有2個屬性:_Person__age
, _Person__gender
,這個屬性其實就是之前定義的__age
和__gender
,因為是私有屬性,於是Python直接修改了這個屬性的名字,改成了:_類名+私有屬性。於是,其實我們可以通過該屬性名進行調用:
>>> print(zhangsan._Person__gender)
>>> print(zhangsan._Person__age)
>>> print(Person._Person__age)
男
18
18
私有屬性的修改
class Person:
__age = 18
def __init__(self):
self.name = '張三'
self.__gender = '男'
zhangsan = Person()
print('通過對象修改對象私有屬性', '+' * 30)
print(zhangsan._Person__gender)
zhangsan._Person__gender = '女'
print(zhangsan._Person__gender)
print('通過對象修改類私有屬性', '+' * 30)
print(zhangsan._Person__age)
zhangsan._Person__age = 30
print(zhangsan._Person__age)
print(Person._Person__age)
print('通過類修改類私有屬性', '+' * 30)
print(Person._Person__age)
Person._Person__age = 25
print(Person._Person__age)
print(zhangsan._Person__age)
通過對象修改對象私有屬性 ++++++++++++++++++++++++++++++
男
女
通過對象修改類私有屬性 ++++++++++++++++++++++++++++++
18
30
18
通過類修改類私有屬性 ++++++++++++++++++++++++++++++
18
25
30
我們可以看到,如同一般的屬性一樣,對於類屬性,對象修改後不會影響到類,類修改後也不會影響到對象。
註意:按照約定俗成的規定,以一個下劃線開頭的實例變數名(例如_age)在外部是可以直接訪問的(弱私有),但是這個形式的變數表達的意思是,“雖然我可以被訪問,但是請把我視為私有變數,不要隨意訪問”。一般地在IDE中也會有所提示:保護成員的訪問類。
6.3.3 類屬性和對象屬性的區別
現在我們來總結一下類屬性和對象屬性的區別。
在定義時,使用關鍵字self
來定義對象屬性。而類屬性不需要,只需要在類最內層直接為變數賦值即可。該變數就是類屬性。
在訪問時,可以通過對象.
的方式直接訪問到一般對象屬性和一般類屬性,而類.
的方式只能訪問到一般類屬性。對於私有屬性無法直接訪問,但是可以通過x._類名+屬性名的方式訪問到。同樣的,不能通過類.
的方式訪問到對象的私有屬性。
在修改時,可以訪問就可以修改,只不過對於類屬性,對象修改後不會影響到類,類修改後也不會影響到對象。而對象屬性,只有對象能夠訪問和修改,類則無法訪問。