We're looking for a user researcher to understand the needs of developers and designers. Is this you or someone you know? Check out the post: https://mzl.la/2IGzdXS

Learn web development

快速理解物件導向程式設計

跳到:

翻譯不完整。請協助 翻譯此英文文件

導論

這個教程會透過範例碼與簡單而實際的解釋,說明如何入門物件導向程式設計(object-oriented programming)。

這個教程是針對這樣的你:

  • 你已經知道如何在其他語言使用類別(class)與物件(object)而你只是想知道如何在 Python 裡實做。
  • 你不懂如何使用物件,而你想用簡單、並省去大篇幅的理論下理解。

這個教程不是針對這樣的你:

  • 你對進階的 Python 程式設計有興趣,想對 Python 的內部工作機制有深切的理解。

如果你知道何謂物件,你可以略過導論

何謂物件(Object)?

創建物件就像是創造你自己的變數型別(variable type)。

這個物件可以包含好幾個變數(稱為屬性,attributes/properties),裡面儲存不同型別的資料。這個物件也可以包含已經自己設定好的函式(稱為 methods),用於操作物件的屬性。

你可以用同一個型別去創建很多個物件(同一個類別),每個物件都有屬於自己的數值。

如果你要為銀行設計一個程式,你要為用戶的帳戶創建一個物件。每個新用戶都會有包含各自資訊的物件。

範例:

object_Account1 = BankAccount()    # 創建兩個新物件
object_Account2 = BankAccount()    # newAccount 是你所創建的 type 名

print object_Account1.userName    # Prints the name of the account
print object_Account1.balance    # Prints the account balance

print object_Account2.userName    # Prints a different name
print object_Account2.balance    # Prints a different balance

這兩個物件都屬於同一個類別,所以這些變數有同一個變數(also called properties or attributes)但有著不同的數值。

物件也各自能擁有在屬性上操作的函式(又稱作方法,method)。

print object_Account1.withdrawMoney(100)
print object_Account2.depositMoney(300)

一個物件的屬性分方法都是由物件的類別所以定義。

物件導向程式設計被認為是現在程式設計方法中最實用的方法。

有完整的理論。

所以讓我們現在開始實做一些程式

建立一個有方法與屬性的類別:

class BankAccount:
    """ Class for Bank Accounts"""

    type = 'Normal Account'    # variable shared by all objects of the class

    def __init__(self, name):
        # default variables unique to each object:
        self.userName = name
        self.balance = 0.0

    # Object Methods:

    def showBalance(self):
        print self.balance
        return

    def withdrawMoney(self, amount):
        self.balance -= amount
        return

    def depositMoney(self, amount):
        self.balance += amount
        return

這個特殊的方法 __init__() 會在物件被創見時自動執行。

你可以傳送參數給它,並且使用客製化的資料去創建物件。

從一個類別建立物件並使用它:

object1 = BankAccount("Im 1")    # create new instance of ClassName
object2 = BankAccount("Me 2")    # create another instance

# access object properties
print object1.userName    #'Im 1'
print object2.userName    #'Me 2'

# access object methods
object1.depositMoney(100)
object2.depositMoney(200)

print object1.balance    # 'Im 1'
print object2.balance    # 'Me 2'
# same as:
object1.showBalance()    # 100
object2.showBalance()    # 200

print object1.type    # 'Normal Account'
print object2.type    # 'Normal Account'

藉由簡單的設定值,你也可以給不同的物件設定新的特殊屬性。

也可以透過'del' 去移除物件的屬性。

object1.discount_code = 'secret'

print object1.discount_code    # 'secret'
print object2.discount_code    # Throws Error: AttributeError: object2 instance has no attribute 'discount_code'

del object1.discount_code    # back to how it originally was

 

易懂原理
 

你會意識到在python 裡任何東西都是物件。 代表在python 中所有的東西都有類別。你可以藉由預設屬性 __class__: 來找到物件屬於哪個類別。

account3 = BankAccount()
print account3.__class__    # __main__.BankAccount

string = 'Cat'
print string.__class__        # <type 'str'>

所以, [1,2].reverse() 是一個原生的類別'list'。

繼承(Inheritance)

你可以建立一個新的繼承其他類別所有方法跟屬性的類別,但你依然可以給予新的類別自己的屬性去擴充它的功能:

class ExecutiveAccount( BankAccount ):
    # Overriden attribute
    type = 'Executive Account'

    # Extended functionality
    def requestCredit(self, amount):
        self.balance += amount

executive = ExecutiveAccount()

當你建立一個物件屬性,直譯器(interpreter)會尋找這個物件的類別。如果找不到,直譯器會繼續尋找類別的繼承練(class inheritance chain)直到找到源頭為止。

你可以透過下面程式覆寫類別呼叫原本的屬性:

class SpecialExecutiveAccount( ExecutiveAccount ):
    def requestCredit(self, amount):
        self.balance = ExecutiveAccount.requestCredit(self, amount)
        return

__init__() 方法不會被繼承。

你可以使用isinstance() 來確認一個物件是否是某個類別的物件或者下一層的物件。

你可以使用issubclass() 來確認一個類別是否是由某個類別衍生。

isinstance(executive, SpecialExecutiveAccount)        # True
isinstance(executive, BankAccount)            # True, derived
issubclass(SpecialExecutiveAccount, BankAccount)    # True

多重繼承(Multiple Inheritance)

這裡支援多重繼承:

class CustomizedClass( ExecutiveAccount, EnterpriseAccount, InternationalAccount ):
    # . . .

If the interpreter doesn't find a requested attribute in the class, the interpreter proceeds left to right, in Executive and then in Enterprise and so on.

Iterators

你或許知道你可以使用迴圈在python物件中迭代子元素。

for i in ['a', 'b', 'c']: print i
# 'a'
# 'b'
# 'c'

for i in 'abc': print i # same as above,

你也可以透過 iter(): 方法迭代子

iterator = iter('abc')
iterator.next() # 'a'
iterator.next() # 'b'
iterator.next() # 'c'

 

你可以透過定義特殊的__iter__() 方法,與接著定義next() 方法,為你的物件增加迭代的功能:

class IterableAccount( BankAccount ):
    def __init__(self, name):
        self.userName = name
        self.index = len(self.userName)

    def __iter__(self):
        return self

    def next(self):
        # iterators will iterate through the userName in reverse order
        if self.index == 0:
            # 如果沒有元素了就停止回傳,並觸發StopIteration
            raise StopIteration
        self.index -= 1
        return self.userName[self.index]

iterable = IterableAccount ('stack')
for i in iterable: print i
# 'k'
# 'c'
# 'a'
# 't'
# 's'

 

文件標籤與貢獻者

此頁面的貢獻者: linzino, iigmir
最近更新: linzino,