Python從設計之初就已經是一門物件導向的語言,也因為如此,在Python中創建一個類別和物件是很容易的。以下這篇文章將詳細為大家介紹關於Python物件導向程式設計的知識點,需要的朋友可以參考借鑒,下面來一起看看吧。
前言
如果你以前沒有接觸過物件導向的程式語言,那你可能需要先了解一些物件導向語言的一些基本特徵,在腦中頭形成一個基本的物件導向的概念,這有助於你更容易的學習Python的物件導向程式設計。
接下來我們就來了解關於Python物件導向程式設計的知識點吧。
類別與實例
類別是物件的定義,而實例是"真正的實體",它存放了類別中所定義的對象的具體資訊。
類別、屬性和方法命名規範
#類別名稱通常由大寫字母打頭。這是標準慣例,可以幫助你識別類,特別是在實例化過程中(有時看起來像函數調用)。還有,資料屬性(變數或常數)聽起來應該是資料值的名字,方法名稱要指出對應物件或值的行為。
另一種表達方式是:資料值應該使用名詞作為名字,方法使用謂詞(動詞加物件)。資料項是操作的物件、方法應表示程式設計師想要在物件進行什麼操作。
在定義的類別中,大致遵循這樣的方針,資料值像 “name”, “phone” 和 “email”,行為如 “updatePhone”,“updateEmail”。這就是常說的 「混合記法(mixedCase)」 或 「駱駝記法(camelCase)」。 Python 規格建議使用駱駝記法的底線方式,例如, “update_phone”,“update_email”。類別也要細致命名,像是 “AddrBookEntry”, “RepairShop” 等等就是個很好的名字。
class AddrBookEntry(object): def init(self, name, phone, email): self.name = name self.phone = phone self.email = email def update_phone(self, phone): self.phone = phone def update_email(self. email): self.email = email
新式類別與舊式類別
#新式類別和經典類別宣告的最大不同在於,所有新式類別必須繼承至少一個父類別。如果沒有可繼承的類,則可繼承 object 類別。 object 是「所有類別之母」 ,它位於所有類別繼承結構的最上層。如果沒有直接或間接的子類化一個對象,那麼就定義了一個經典類別。即如果沒有指定一個父類,或者如果所子類化的基本類沒有父類,這樣就是創建了一個經典類。
在 Python3 中定義的類,預設就是新式類,而在 Python2 中要定義一個新式類別則必須繼承 object 或繼承一個新式類。
self 變數
類別的方法與普通的函數只有一個特別的區別,即它們必須有一個額外的第一個參數名稱,但在呼叫這個方法的時候你不必為這個參數賦值,Python 會提供這個值。這個特別的變數指物件本身,按照慣例它的名稱是 self。雖然可以給這個參數任何名稱,但強烈建議使用 self 這個名稱,其他名稱都是不贊成使用的。
init() 方法
#init()
類似於類別建構器,但實際上並不是一個構造器。 Python 建立實例後,在實例化過程中,呼叫init()
方法,當一個類別被實例化時,就可以定義額外的行為,例如,設定初始值或執行一些初步診斷程式碼,這主要是在實例被創建後,實例化呼叫返回這個實例之前,去執行某些特定的任務或設定。
綁定及非綁定方法
在 Python 中,存取類別的方法可以透過實例也可以透過類別來直接存取。但是 Python 嚴格要求,沒有實例,方法是不能被呼叫的。這個限制即 Python 所描述的綁定概念(binding),在此,方法必須綁定(到一個實例)才能直接被呼叫。非綁定的方法可能可以被調用,但實例物件一定要明確給出,才能確保調用成功。然而,不管是否綁定,方法都是它所在的類別的固有屬性,即使它們幾乎總是透過實例來呼叫的。在 Python 中的類別方法也是一種物件。可以簡單的理解就是,透過類別直接存取的方法稱為“未綁定的方法”,而透過實例存取的方法稱為“綁定的方法”:
1. 未綁定定的類別方法:沒有self
#通过类来引用方法返回一个未绑定方法对象。要调用它,你必须显示地提供一个实例作为第一个参数。
2. 绑定的实例方法:有 self
通过实例访问方法返回一个绑定的方法对象。Python 自动地给方法绑定一个实例,所以我们调用它时不用再传一个实例参数。
示例:
class Test: def func(self, message): print message object1 = Test() x = object1.func x("绑定方法对象,实例是隐藏的") t = Test.func t(object1, "未绑定方法对象,需要传递一个实例") # t("未绑定方法对象,需要传递一个实例") # 错误的调用
类属性与实例属性
类属性仅是与类相关的数据值,和实例属性不同,类属性和实例无关。这些值像静态成员那样被引用,即使在多次实例化中调用类,它们的值都保持不变。不管如何,静态成员不会因为实例而改变它们的值,除非实例中显式改变它们的值。 实例属性与类属性的比较,类似于自动变量和静态变量,但这只是笼统的类推。在你对自动变量和静态变量还不是很熟的情况下,不要深究这些。
类和实例都是名字空间。类是类属性的名字空间,实例则是实例属性的。
可采用类来访问类属性,如果实例没有同名的属性的话,也可以用实例来访问。
私有化
Python并不直接支持私有方式,而要靠程序员自己把握在外部进行特性修改的时机。
为了让方法或者特性变为私有(从外部无法访问),只要在它的名字前面加上双下划线即可。由双下划线 开始的属性在运行时被“混淆”,所以直接访问是不允许的。
实际上,在 Python 带有双下划线的属性或方法并非正真意义上的私有,它们仍然可以被访问。在类的内部定义中,所有以双下划线开始的名字都被“翻译”成前面加上单下划线和类名的形式:
>>> class TestObj(object): ... war = "world" ... ... def init(self): ... self.har = "hello" ... ... def foo(self): ... print(self.har + self.war) ... ... ... >>> t = TestObj() >>> dir(t) ['_TestObjfoo', '_TestObjhar', '_TestObjwar', 'class', 'delattr', 'dict', 'dir', 'doc', 'eq', 'format', 'ge', 'getat tribute', 'gt', 'hash', 'init', 'le', 'lt', 'module', 'ne', 'new', 'reduce', 'reduce_ex', 'repr', 'setattr ', 'sizeof', 'str', 'subclasshook', 'weakref'] >>> t.war Traceback (most recent call last): File "<input>", line 1, in <module> t.war AttributeError: 'TestObj' object has no attribute 'war' >>> t.har Traceback (most recent call last): File "<input>", line 1, in <module> t.har AttributeError: 'TestObj' object has no attribute 'har' >>> t.foo() Traceback (most recent call last): File "<input>", line 1, in <module> t.foo() AttributeError: 'TestObj' object has no attribute 'foo' >>> t._TestObjwar 'world' >>> t._TestObjhar 'hello' >>> t._TestObjfoo() helloworld
slots 类属性
正常情况下,当我们定义了一个 class,创建了一个 class 的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性。在 Python 中默认用字典来存储实例的属性。
示例:
>>> class A(): ... pass ... >>> a = A() >>> a.name = "huoty" >>> a.age = 25 >>> print a.name huoty >>> print a.age 25 >>> a.dict {'age': 25, 'name': 'huoty'}
字典位于实例的“心脏” 。 dict
属性跟踪所有实例属性。举例来说,你有一个实例 inst,它有一个属性 foo,那使用 inst.foo
来访问它与使用 inst.dict['foo']
来访问是一致的。
字典会占据大量内存,如果你有一个属性数量很少的类,但有很多实例,那么正好是这种情况。为内存上的考虑,可以使用 slots
属性来替代 dict
。
, slots
是新式类的特性。基本上, slots
是一个类变量,由一序列对象组成,由所有合法标识构成的实例属性的集合来表示。它可以是一个列表,元组或可迭代对象。也可以是标识实例能拥有的唯一的属性的简单字符串。任何试图创建一个其名不在 slots
中的名字的实例属性都将导致 AttributeError 异常:
>>> class SlotedClass(object): ... slots = ("foo", "bar") ... ... >>> c = SlotedClass() >>> c.foo = 42 >>> c.bar = "hello" >>> c.goo = "don't think so" Traceback (most recent call last): File "<input>", line 1, in <module> AttributeError: 'SlotedClass' object has no attribute 'goo'
这种特性的主要目的是节约内存。其副作用是某种类型的"安全",它能防止用户随心所欲的动态增加实例属性。带 slots
属性的类定义不会存在 dict
了(除非你在 slots
中增加 dict
元素)。
总结
【相关推荐】
1. Python免费视频教程
3. Python学习手册
以上是細說物件導向的python程式碼細節的詳細內容。更多資訊請關注PHP中文網其他相關文章!