1. 程式人生 > >[譯]Python提高:Python類和麵向物件程式設計

[譯]Python提高:Python類和麵向物件程式設計

原文作者:Jeff Knupp

原文連結:這裡

class是Python的基礎構建快。它是很多流行的程式和庫,以及Python標準庫的基礎依託。理解類是什麼,什麼時候使用,以及它們如何有用至關重要,這也是本文的目的。在這個過程中,我們會探討“面向物件程式設計”的含義,以及它與Python類之間的聯絡。

一切都是物件…

class關鍵字究竟是什麼?跟它基於函式的def表兄弟類似,它用於定義事物。def用來定義函式,class用來定義。什麼是類?就是一個數據和函式(在類中定義時,通常叫做“方法”)的邏輯分組。

“邏輯分組”是什麼意思?一個類可以包含我們希望的任何資料和函式(方法)。我們嘗試建立事物之間有邏輯聯絡的類,而不是把隨機的事物放在“類”名下面。很多時候,類都是基於真實世界的物體(比如Customer

Product)。其它時候,類基於系統中的概念,比如HTTPRequestOwner

不管怎麼樣,類是一種建模技術,一種思考程式的方式。當你用這種方式思考和實現你的系統時,被稱為使用面向物件程式設計。“類”和“物件”經常互換使用,但實際上它們並不相同。理解它們是什麼和它們是如何工作的關鍵是理解它們之間的區別。

..所以一切都有一個類?

類可以看做是建立物件的藍圖。當我使用class關鍵字定義一個Customer類時,我並沒有真正建立一個顧客。相反,我建立的是構建顧客物件的說明手冊。讓我們看以下示例程式碼:

class Customer(object):
    """A customer of ABC Bank with a checking account. Customers have the
    following properties:

    Attributes:
        name: A string representing the customer's name.
        balance: A float tracking the current balance of the customer's account.
    """
def __init__(self, name, balance=0.0): """Return a Customer object whose name is *name* and starting balance is *balance*.""" self.name = name self.balance = balance def withdraw(self, amount): """Return the balance remaining after withdrawing *amount* dollars."""
if amount > self.balance: raise RuntimeError('Amount greater than available balance.') self.balance -= amount return self.balance def deposit(self, amount): """Return the balance remaining after depositing *amount* dollars.""" self.balance += amount return self.balance

class Customer(object)並沒有建立一個新的顧客。我們只是定義了一個Customer,並不意味著建立了一個顧客;我們僅僅勾勒出建立Customer物件的藍圖。用正確的引數數量(去掉self,我們馬上會討論)呼叫類的__init__方法可以建立一個顧客。

因此,要使用通過class Customer(用於建立Customer物件)定義的“藍圖”,可以把類名看做一個函式來呼叫:jeff = Customer('Jeff Knupp', 1000.0)。這行程式碼表示:使用Customer藍圖建立一個新物件,並把它指向jeff

被稱為例項jeff物件Customer的實現版本。我們呼叫Customer()之前,不存在Customer物件。當然,我們可以建立任意多個Customer物件。但是不管我們建立多少Customer例項,仍然只有一個Customer

self

對應所有Customer方法來說,self引數是什麼?當然,它是例項。換一種方式,像withdraw這樣的方法,定義了從某些抽象顧客的賬戶中取錢的指令。呼叫jeff.withdraw(1000.0)把這些指令用在jeff例項上。

所以,當我們說:def withdraw(self, amount):,我們的意思是:這是你如何從一個顧客物件(我們稱為self)和一個美元數字(我們稱為amount)取錢。selfCustomer例項,在它上面呼叫withdraw。這也不是我做類比。jeff.withdraw(1000.0)只是Customer.withdraw(jeff, 1000.0)的簡寫,也是完全有限的程式碼。

__init__

self可能對其它方法也有意義,但是__init__呢?當我們呼叫__init__時,我們在建立一個物件的過程中,為什麼已經有了self?儘管不完全適合,Python還是允許我們擴充套件self模式到物件的構造。想象jeff = Customer('Jeff Knupp', 1000.0)等價於jeff = Customer(jeff, 'Jeff Knupp', 1000.0);傳入的jeff也是同樣的結果。

這就是為什麼呼叫__init__時,我們通過self.name = name初始化物件。記住,因為self是例項,所以它等價於jeff.name = name,它等價於jeff.name = 'Jeff Knupp'。同樣的,self.balance = balance等價於jeff.balance = 1000.0。這兩行程式碼之後,我們認為Customer物件已經“初始化”,可以被使用。

完成__init__後,呼叫者可以假設物件已經可以使用。也就是,呼叫jeff = Customer('Jeff Knupp', 1000.0)後,我們可以在jeff上呼叫depositwithdrawjeff是一個完全初始化的物件。

我們定義了另外一個稍微不同的Customer類:

class Customer(object):
    """A customer of ABC Bank with a checking account. Customers have the
    following properties:

    Attributes:
        name: A string representing the customer's name.
        balance: A float tracking the current balance of the customer's account.
    """

    def __init__(self, name):
        """Return a Customer object whose name is *name*.""" 
        self.name = name

    def set_balance(self, balance=0.0):
        """Set the customer's starting balance."""
        self.balance = balance

    def withdraw(self, amount):
        """Return the balance remaining after withdrawing *amount*
        dollars."""
        if amount > self.balance:
            raise RuntimeError('Amount greater than available balance.')
        self.balance -= amount
        return self.balance

    def deposit(self, amount):
        """Return the balance remaining after depositing *amount*
        dollars."""
        self.balance += amount
        return self.balance

它看起來是一個合理的替代者;在使用例項之前,只需要簡單的呼叫set_balance。但是,沒有一種方式可以告訴呼叫者這麼做。即使我們在文件中說明了,也不能強制呼叫者在呼叫jeff.withdraw(100.0)之前呼叫jeff.set_balance(1000.0)jeff例項在呼叫jeff.set_balance之前沒有balance屬性,這意味著物件沒有“完全”初始化。

簡單來說,不要在__init__方法之外引入新的屬性,否則你會給呼叫一個沒有完全初始化的物件。當然也有例外,但這是一個需要記住的原則。這是物件一致性這個大概念的一部分:不應該有任何一系列的方法呼叫可能導致物件進入沒有意義的狀態。

不變性(比如“賬戶餘額總是非負數”)應該在方法進入和退出時都保留。物件不可能通過呼叫它的方法進入無效狀態。不用說,一個物件也應該從一個有效的狀態開始,這就是為什麼在__init__方法中初始化所有內容是很重要的。

例項屬性和方法

定義在類中的函式稱為“方法”。方法可以訪問包含在物件例項中的所有資料;它們可以訪問和修改之前在self上設定的任何內容。因為它們使用self,所以需要使用類的一個例項。基於這個原因,它們通常被稱為“例項方法”。

如果有“例項方法”,一定也會有其它型別的方法,對吧?是的,確實有,但這些方法有些深奧。我們會在這裡簡略的介紹一下,但是可以更深入的研究這些主題。

靜態方法

類屬性是在類級別上設定的屬性,相對的是例項級別。普通屬性在__init__方法中引入,但有些屬性適用於所有例項。例如,思考下面Car物件的定義:

class Car(object):

    wheels = 4

    def __init__(self, make, model):
        self.make = make
        self.model = model

mustang = Car('Ford', 'Mustang')
print mustang.wheels
# 4
print Car.wheels
# 4

不管makemodel是什麼,一輛Car總是有四個Wheels。例項方法可以通過跟訪問普通屬性一樣訪問這些屬性:通過self(比如,self.wheels)。

有一種稱為靜態方法的方法,它們不能訪問self。跟類屬性類似,它們不需要例項就能工作。因為例項總是通過self引用,所以靜態方法沒有self引數。

下面是Car類的一個有效的靜態方法:

class Car(object):
    ...
    def make_car_sound():
        print 'VRooooommmm!'

不管我們擁有什麼型別的汽車,它總是發出相同的聲音。為了說明這個方法不應該接收例項作為第一個引數(比如“普通”方法的self),可以使用@staticmethod裝飾器,把我們的定義變成:

class Car(object):
    ...
    @staticmethod
    def make_car_sound():
        print 'VRooooommmm!'

類方法

靜態方法的一個變種是類方法。它傳遞,而不是例項作為第一個引數。它也使用裝飾器定義:

class Vehicle(object):
    ...
    @classmethod
    def is_motorcycle(cls):
        return cls.wheels == 2

現在類方法可能沒有太大的意義,但它通常與下一個主題聯絡在一起:繼承

繼承

面向物件程式設計作為建模工具非常有用,引入繼承的概念後,它真正變強大了。

繼承是“子”類衍生“父”類的資料和行為的過程。有一個例項可以明確的幫助我們理解。

想象我們經營了一家汽車銷售店。我們銷售所有型別的車輛,從摩托車到卡車。我們通過價格與競爭對手區分開來。特別是我們如何確定車輛的價格:50001010,000,汽車是8,0004,000。

如果我們想用面對物件技術為汽車銷售店建立一個銷售系統,應該怎麼做?物件是什麼?我們可能有一個Sale類,一個Customer類,一個Inventor類等等,但我們肯定有一個CarTruckMotorcycle類。

這些類應該是什麼樣的?用我們已經學會的知識,以下是Car類的一種實現:

class Car(object):
    """A car for sale by Jeffco Car Dealership.

    Attributes:
        wheels: An integer representing the number of wheels the car has.
        miles: The integral number of miles driven on the car.
        make: The make of the car as a string.
        model: The model of the car as a string.
        year: The integral year the car was built.
        sold_on: The date the vehicle was sold.
    """

    def __init__(self, wheels, miles, make, model, year, sold_on):
        """Return a new Car object."""
        self.wheels = wheels
        self.miles = miles
        self.make = make
        self.model = model
        self.year = year
        self.sold_on = sold_on

    def sale_price(self):
        """Return the sale price for this car as a float amount."""
        if self.sold_on is not None:
            return 0.0  # Already sold
        return 5000.0 * self.wheels

    def purchase_price(self):
        """Return the price for which we would pay to purchase the car."""
        if self.sold_on is None:
            return 0.0  # Not yet sold
        return 8000 - (.10 * self.miles)

    ...

看起來非常合理。當然,類中可能還有其它方法,但我已經展示了兩個我們感興趣的方法:sale_pricepurchase_price。我們之後會看到為什麼這些很重要。

我們已經有了Car類,也許我們應該建立Truck類。我們按同樣的方式建立:

class Truck(object):
    """A truck for sale by Jeffco Car Dealership.

    Attributes:
        wheels: An integer representing the number of wheels the truck has.
        miles: The integral number of miles driven on the truck.
        make: The make of the truck as a string.
        model: The model of the truck as a string.
        year: The integral year the truck was built.
        sold_on: The date the vehicle was sold.
    """

    def __init__(self, wheels, miles, make, model, year, sold_on):
        """Return a new Truck object."""
        self.wheels = wheels
        self.miles = miles
        self.make = make
        self.model = model
        self.year = year
        self.sold_on = sold_on

    def sale_price(self):
        """Return the sale price for this truck as a float amount."""
        if self.sold_on is not None:
            return 0.0  # Already sold
        return 5000.0 * self.wheels

    def purchase_price(self):
        """Return the price for which we would pay to purchase the truck."""
        if self.sold_on is None:
            return 0.0  # Not yet sold
        return 10000 - (.10 * self.miles)

    ...

幾乎跟Car類一模一樣。程式設計中最重要的原則之一(通常不只是處理物件時)是“DRY”或者“Don’t Repeat Yourself”。確定無疑,我們在這裡重複了。實際上,Car類和Truck類只有一個字元不同(除了註釋)。

出什麼事了?我們哪裡做錯了?我們的主要問題是我們直奔概念:CarTruck是真實的事物,直覺讓有形的物件成為類。但是它們共享這麼多資料和功能,似乎我們可以在這裡引入一個抽象。沒錯,它就是Vehicle

抽象類

Vehicle不是真實世界的物件。而是一個概念,它包含某些真實世界中的物件(比如汽車,卡車和摩托車)。我們可以用這個事實來移除重複程式碼,即每個物件都被看做是一臺車輛。通過定義Vehicle類達到目的:

class Vehicle(object):
    """A vehicle for sale by Jeffco Car Dealership.

    Attributes:
        wheels: An integer representing the number of wheels the vehicle has.
        miles: The integral number of miles driven on the vehicle.
        make: The make of the vehicle as a string.
        model: The model of the vehicle as a string.
        year: The integral year the vehicle was built.
        sold_on: The date the vehicle was sold.
    """

    base_sale_price = 0

    def __init__(self, wheels, miles, make, model, year, sold_on):
        """Return a new Vehicle object."""
        self.wheels = wheels
        self.miles = miles
        self.make = make
        self.model = model
        self.year = year
        self.sold_on = sold_on


    def sale_price(self):
        """Return the sale price for this vehicle as a float amount."""
        if self.sold_on is not None:
            return 0.0  # Already sold
        return 5000.0 * self.wheels

    def purchase_price(self):
        """Return the price for which we would pay to purchase the vehicle."""
        if self.sold_on is None:
            return 0.0  # Not yet sold
        return self.base_sale_price - (.10 * self.miles)

通過替換class Car(object)中的object,我們可以讓CarTruck繼承Vehicle類。括號中的類表示從哪個類繼承(object實際上是“沒有繼承”。我們一會兒討論為什麼這麼寫)。

現在我們可以直截了當的定義CarTruck

class Car(Vehicle):

    def __init__(self, wheels, miles, make, model, year, sold_on):
        """Return a new Car object."""
        self.wheels = wheels
        self.miles = miles
        self.make = make
        self.model = model
        self.year = year
        self.sold_on = sold_on
        self.base_sale_price = 8000


class Truck(Vehicle):

    def __init__(self, wheels, miles, make, model, year, sold_on):
        """Return a new Truck object."""
        self.wheels = wheels
        self.miles = miles
        self.make = make
        self.model = model
        self.year = year
        self.sold_on = sold_on
        self.base_sale_price = 10000

這樣可以工作了,但還有一些問題。首先我們仍然有很多重複的程式碼。最終我們會處理完所有重複的程式碼。其次,更大的問題是,我們引入了Vehicle類,但我們真的允許呼叫者建立Vehicle物件(而不是CarTruck)?Vehicle僅僅是一個概念,不是真實的事物,所以下面程式碼的意義是:

v = Vehicle(4, 0, 'Honda', 'Accord', 2014, None)
print v.purchase_price()

Vehicle沒有base_sale_price,只有各個子類(比如CarTruck)有。問題在於Vehicle應該是一個Abstract Base ClassAbstract Base Class是隻可以被繼承的類;不能建立ABC的例項。這意味著如果Vehicle是一個ABC,那麼下面的程式碼就是非法的:

v = Vehicle(4, 0, 'Honda', 'Accord', 2014, None)

禁止這一點是有意義的,因為我們從來不會直接使用Vehicle。我們只想用它抽取一些通用的資料和行為。我們如何讓一個類成為ABC?很簡單!abc模組包括一個稱為ABCMeta的元類。設定一個類的元類為ABCMeta,並讓其中一個方法為虛擬的,就能讓類成為一個ABCABC規定,虛擬方法必須在子類中存在,但不是必須要實現。例如,Vehicle類可以如下定義:

from abc import ABCMeta, abstractmethod

class Vehicle(object):
    """A vehicle for sale by Jeffco Car Dealership.


    Attributes:
        wheels: An integer representing the number of wheels the vehicle has.
        miles: The integral number of miles driven on the vehicle.
        make: The make of the vehicle as a string.
        model: The model of the vehicle as a string.
        year: The integral year the vehicle was built.
        sold_on: The date the vehicle was sold.
    """

    __metaclass__ = ABCMeta

    base_sale_price = 0

    def sale_price(self):
        """Return the sale price for this vehicle as a float amount."""
        if self.sold_on is not None:
            return 0.0  # Already sold
        return 5000.0 * self.wheels

    def purchase_price(self):
        """Return the price for which we would pay to purchase the vehicle."""
        if self.sold_on is None:
            return 0.0  # Not yet sold
        return self.base_sale_price - (.10 * self.miles)

    @abstractmethod
    def vehicle_type():
        """"Return a string representing the type of vehicle this is."""
        pass

因為vehicle_type是一個abstractmethod,所以我們不能直接建立Vehicle例項。只要CarTruckVehicle繼承,定義了vehicle_type,我們就能例項化這些類。

返回Car類和Truck類中的重複程式碼,看看我們是否可以把通用的功能提升到基類Vehicle中:

from abc import ABCMeta, abstractmethod
class Vehicle(object):
    """A vehicle for sale by Jeffco Car Dealership.


    Attributes:
        wheels: An integer representing the number of wheels the vehicle has.
        miles: The integral number of miles driven on the vehicle.
        make: The make of the vehicle as a string.
        model: The model of the vehicle as a string.
        year: The integral year the vehicle was built.
        sold_on: The date the vehicle was sold.
    """

    __metaclass__ = ABCMeta

    base_sale_price = 0
    wheels = 0

    def __init__(self, miles, make, model, year, sold_on):
        self.miles = miles
        self.make = make
        self.model = model
        self.year = year
        self.sold_on = sold_on

    def sale_price(self):
        """Return the sale price for this vehicle as a float amount."""
        if self.sold_on is not None:
            return 0.0  # Already sold
        return 5000.0 * self.wheels

    def purchase_price(self):
        """Return the price for which we would pay to purchase the vehicle."""
        if self.sold_on is None:
            return 0.0  # Not yet sold
        return self.base_sale_price - (.10 * self.miles)

    @abstractmethod
    def vehicle_type(self):
        """"Return a string representing the type of vehicle this is."""
        pass

現在CarTruck類變成:

class Car(Vehicle):
    """A car for sale by Jeffco Car Dealership."""

    base_sale_price = 8000
    wheels = 4

    def vehicle_type(self):
        """"Return a string representing the type of vehicle this is."""
        return 'car'

class Truck(Vehicle):
    """A truck for sale by Jeffco Car Dealership."""

    base_sale_price = 10000
    wheels = 4

    def vehicle_type(self):
        """"Return a string representing the type of vehicle this is."""
        return 'truck'

這完全符合我們的直覺:就我們的系統而言,汽車和卡車之間的唯一區別是基礎售價。

定義一個Motocycle類非常簡單:

class Motorcycle(Vehicle):
    """A motorcycle for sale by Jeffco Car Dealership."""

    base_sale_price = 4000
    wheels = 2

    def vehicle_type(self):
        """"Return a string representing the type of vehicle this is."""
        return 'motorcycle'

繼承和LSP

儘管看起來我們用繼承處理了重複,但我們真正做的是簡單的提供適當級別的抽象。抽象是理解繼承的關鍵。我們已經看到使用繼承的一個附帶作用是減少重複的程式碼,但從呼叫者的角度來看呢?使用繼承如何改變程式碼?

事實證明有一點。想象我們有兩個類:DogPerson,我們想寫一個函式,它接收任何兩種物件型別,並列印該例項是否可以說話(狗不能,人可以)。我們可能這麼編寫程式碼:

def can_speak(animal):
    if isinstance(animal, Person):
        return True
    elif isinstance(animal, Dog):
        return False
    else:
        raise RuntimeError('Unknown animal!')

只有兩種型別的動物時沒問題,但是如何有20種呢,或者200種?那麼if...elif會相當長。

這裡關鍵是can_speak不應該關心處理的動物型別,動物類本身應該告訴我們它能否說話。通過引入基類Animal,其中定義can_speak,可以避免函式的型別檢查。只要知道是傳進來的是Animal,確定能否說話很簡單:

def can_speak(animal):
    return animal.can_speak()

這是因為PersonDog(或者其它任何從Animal繼承的類)遵循Liskov Substitution Principle。這表示我們可以在希望父類(Animal)的地方,使用子類(比如PersonDog)替換。這聽起來很簡單,但它是interface的基礎。

總結

希望你們學會了什麼是Python類,為什麼它們很有用,以及如何使用。類和麵向物件程式設計很深奧。確實,它涉及電腦科學的核心。本文不是對類的詳細研究,也不應該是你的唯一參考。網路上有數以千計的OOP和類的解釋,如果本文對你不合適,搜尋會讓你找到更適合你的。

一如既往,歡迎在評論中更正和討論。只要保持禮貌就行。

相關推薦

[]Python提高Python和麵物件程式設計

原文作者:Jeff Knupp 原文連結:這裡 class是Python的基礎構建快。它是很多流行的程式和庫,以及Python標準庫的基礎依託。理解類是什麼,什麼時候使用,以及它們如何有用至關重要,這也是本文的目的。在這個過程中,我們會探討“

python:面向過程和麵物件程式設計思想

一、區別 面向過程:在實現的時候,每個過程都需要一個函式 面向物件: 二、面向物件和類 類的組成:以狗為例 (1)類名:(狗) (2)類的屬性:一組資料(狗的毛色,重量等) (3)類的方法

第四節詳細講解Java中的和麵物件思想

前言大家好,我是 Vic,今天給大家帶來詳細講解Java中的類和麵向物件思想的概述,希望你們喜歡類和麵向物件在Java中怎樣理解物件,建立物件和引用;什麼是引用,對於基礎學習的同學,要深入瞭解引用。示例:String str = new String(); ;其中str為引用

PL真有意思(七)資料抽象和麵物件

前言 在之前的名字、作用域那篇提到模組型別,它使程式設計師可以從一個給定抽象出發,通過例項化產生多個例項;再後面是類,它使程式設計師可以定義一族相關的抽象。 在這一篇裡,我們會來看一下面向物件程式設計及其三個基本概念、動態方法約束、多重繼承等等 面向物件程式設計 隨著軟體變得越來越複雜,資料抽象已經變成了軟體

面向函式程式設計和麵物件程式設計的區別和使用

簡述面向函式程式設計和麵向物件程式設計的區別? 什麼時候使用面向函式程式設計?什麼時候使用面向物件程式設計? 函數語言程式設計,顧名思義,這種程式設計是以函式思維做為核心,在這種思維的角度去思考問題。 這種程式設計最重要的基礎是λ演算,接受函式當作輸入和輸出。 面向物件程式設計,這種程

面向過程程式設計和麵物件程式設計的區別

面向過程程式設計 面向過程程式設計是一種以過程為中心的程式設計思想,分析出解決問題的步驟,然後用函式把這些步驟一步一步實現。面向過程程式設計,資料和對資料的操作是分離的。 面向物件程式設計 面向物件程式設計是將事物物件化,通過物件通訊來解決問題。面向物件程式設計,資料和對資料的操作

面向過程和麵物件程式設計的的思想理解

      之所以寫這邊部落格,是因為昨日和一位電子專業的好友,聊起了這個專業問題,我卻沒有用通俗易懂的例子來解釋它們,雖然已經把C語言過了一遍,Java也學了好一段時間,但是真正去向一個外行人解釋,感覺只可意會不言傳的感覺,為此非常的懊惱。 面向過程:是一種以過程為中

面向介面程式設計和麵物件程式設計的區別

我想,對於各位使用面向物件程式語言的程式設計師來說,“介面”這個名詞一定不陌生,但是不知各位有沒有這樣的疑惑:介面有什麼用途?它和抽象類有什麼區別?能不能用抽象類代替介面呢?而且,作為程式設計師,一定經常聽到“面向介面程式設計”這個短語,那麼它是什麼意思?有什麼思想內涵?

面向過程程式設計思想和麵物件程式設計思想

一、面向過程程式設計思想 百度百科這樣解釋: “面向過程”(Procedure Oriented)是一種以過程為中心的程式設計思想。 面向過程其實是最為實際的一種思考方式,就算是面向物件的方法也是含有面向過程的思想。可以說面向過程是一種基礎的方法。它考慮的

元件化程式設計和麵物件程式設計

元件化程式設計: 在向大家詳細介紹C#元件化程式設計之前,首先讓大家瞭解下介面與元件,然後全面介紹C#元件化程式設計。 介面與元件 介面描述了元件對外提供的服務。在元件和元件之間、元件和客戶之間都通過介面進行互動。因此元件一旦釋出,它只能通過預先定義的介面來提供合理的、一致

js的this和麵物件程式設計

    很奇怪的是很多書或資料沒有把這個事情講清楚。     關鍵就是在於沒有一個整體的思維技術模式,問題被隔離了所以反而不容易理解。     我們先看this,這是js的關鍵字,指示函式的上下文物件。     這裡問題就來了,比如: var obj = {};

Python-07Python語法基礎-數據

數據類型 有序 索引 img utf http col 符號 數組 1、基本數據類型 2、列表   在Python中沒有數組!!!和數組類似的就是列表和元組了   列表就是存儲一連串元素的 容器。用[]來表示,是 有序排列的 3、元組   元組裏面的元素也是能進行

Python基礎Python(真累~)

理解 技術 rowspan num 重新 說明 區分 第一個 構造 類的聲明:一、類的屬性(私有屬性和公有屬性)(類屬性)二、類的方法(構造方法、析構方法、自定義方法、特殊成員方法)(靜態方法、類方法、類屬性)三、類的繼承(方法和屬性的繼承,方法的重構)(抽象類,多重繼承)

python(七)與抽象基

imp 匿名 exec int 上下文 增加 abstract 分割 als 一、實例創建   在創建實例時,調用__new__方法和__init__方法,這兩個方法在沒有定義時,是自動調用了object來實現的。python3默認創建的類是繼承了object。 c

python筆記 經典和新式的區別

python 筆記:經典類和新式類的區別 Python 2.x中預設都是經典類,只有顯式繼承了object才是新式類 Python 3.x中預設都是新式類,不必顯式的繼承object 其次: ——新式類物件可以直接通過class屬性獲取自身型別:type ——繼承搜

Python基礎-面向物件和麵過程程式設計區別

前言 OOP,是一種程式設計思想。OOP把物件作為程式的基本單元,一個物件包含了資料和操作資料的函式。哈哈哈,學Python、Java的人表示很開心。 面向過程的程式設計 把計算機程式視為一系列的命令集合,即一組函式的順序執行。為了簡化程式設計,面向過程把

Python技巧(Metaclasses)和利用Type構建的動態(Dynamic Classes)

`metaclass`和`type`關鍵字在Python程式碼中較少被使用(也正因如此,它們的作用也沒有很好的被理解)。在這篇文章中,我們將探究`type()`的型別(types)和跟`metaclasses`相關的`type`的用法。 這是我的型別麼?首先來看`ty

Python-06Python語法基礎-數與字符串

com -1 進行 距離 Coding 開始 mage gin spl 1、數的類型   Python中數的類型主要是有5中,分別有整數型(int)、長整型(long)、浮點型(float)、布爾型(bool)、復數型(complex)   例如: 0 -1 1 -9

Python-10Python語法基礎-運算符與表達式

輸出 false col 先後 邏輯與 尋址 分享 hello 邏輯或 1、Python運算符簡介   1)什麽是運算符     在Python中經常需要對一個或多個數字進行操作,2+3中的+是運算符,"hello"*20中的*也是運算符   2)運算符有哪些     + 

Python-11Python語法基礎-控制流

for 重復 程序代碼 次循環 python 停止 應該 for語句 執行 1、Python中的三種控制流   程序中代碼的執行是有順序的,有的代碼會從上到下按順序執行,有的程序代碼會跳轉著執行,有的程序代碼會選擇不同的分支執行,有的代碼會循環著執行,什麽樣的程序應該選擇分