簡體   English   中英

為什么要在具有功能的模塊上使用python類?

[英]Why use python classes over modules with functions?

我正在自學python(3.x),我正在嘗試了解類的用例。 我開始理解它們的實際作用,但是我正在努力理解為什么要使用類而不是創建帶有函數的模塊。

例如,如何:

class cls1:
    def func1(arguments...):
    #do some stuff


obj1 = cls1()
obj2 = cls1()

obj1.func1(arg1,arg2...)
obj2.func1(arg1,arg2...)

與......不同:

#module.py contents
    def func1(arguments...):
        #do some stuff

import module

x = module.func1(arg1,arg2...)
y = module.func1(arg1,arg2...)

這可能很簡單,但是我無法理解。

到目前為止,我在編寫python程序方面已經取得了相當大的成功,但是它們都具有相當的程序性,並且僅導入基本模塊功能。 上課是我的下一個最大障礙。

如果需要一個類的多個實例,並且希望這些實例不會互相干擾,則可以使用該類。

模塊的行為類似於單例類,因此您只能有一個實例。

編輯:例如,如果您有一個名為example.py的模塊:

    x = 0
    def incr():
           global x
           x = x + 1

    def getX():
           return x

如果您嘗試兩次導入這些模塊:

    import example as ex1
    import example as ex2

    ex1.incr()
    ex1.getX()
    1
    ex2.getX()
    1

這就是為什么僅一次導入模塊,所以ex1和ex2指向同一對象的原因。

只要您僅使用純函數(僅對它們的參數起作用的函數,對於相同的參數集始終返回相同的結果,不依賴於任何全局/共享狀態並且不更改任何內容 ,也不更改其參數)也不是任何全局/共享狀態-沒有任何副作用的IOW函數),那么類的使用確實是有限的。 但這是函數式編程 ,盡管Python在技術上可以以函數樣式使用,但在這里可能不是最佳選擇。

一旦您必須在功能之間共享狀態,並且特別是如果其中某些功能應該更改此共享狀態,則您確實可以使用OO概念。 在函數之間共享狀態的方法主要有兩種:在函數之間傳遞狀態,或使用全局變量。

第二種解決方案-全局狀態-麻煩,首先是因為它使對程序流的理解(因此調試)更加困難,而且還因為它使您的代碼無法重新進入 ,這在很多情況下是肯定的當前常見的用例(多線程執行,大多數服務器端Web應用程序代碼等)。 實際上,它使您的代碼幾乎無法使用或幾乎無法使用,除了簡短的簡單一槍腳本之外的任何事情……

第二種解決方案通常暗示使用半非正式的復雜數據結構(具有給定鍵集的字典,通常包含其他字典,列表,字典列表,集合等),正確地初始化它們並將它們從一個函數傳遞到另一個函數-當然具有在給定數據結構上工作的一組功能。 IOW您實際上是在定義新的復雜數據類型(一個數據結構和對該數據結構的一組操作)時,僅使用該語言提供的最低級別的工具。

類實際上是在更高級別上定義此類數據類型的一種方法,將數據和操作分組在一起。 它們還提供了更多的功能,特別是多態性 ,它使代碼更通用,可擴展,並且使單元測試更加容易。

假設您有一個包含產品的文件或數據庫,並且每個產品都有產品ID,價格,可用性,折扣,以網絡狀態發布以及更多值。 您將擁有包含數千個包含新價格,新產品和折扣的產品的第二個文件。 您想更新值並控制要更改的產品數量和其他統計信息。 您可以使用過程編程和函數式編程來做到這一點,但是您會發現自己試圖找到使之起作用的技巧,並且很可能您會迷失在許多不同的列表和集合中。

另一方面,通過面向對象的編程,您可以創建一個具有實例變量的產品類,該實例變量包括產品ID,舊價格,舊可用性,舊折扣,舊發布狀態以及一些新值(新價格)的實例變量。 ,新的可用性,新的折扣,新的發布狀態)。 您要做的就是讀取第一個文件/數據庫,並為每個產品創建Product類的新實例。 比您可以閱讀第二個文件並找到產品對象的新值。 最后,第一個文件/數據庫的每個產品都將是一個對象,並將被標記並帶有舊值和新值。 這種方式可以更輕松地跟蹤更改,進行統計和更新數據庫。

再舉一個例子。 如果使用tkinter,則可以為頂級窗口創建一個類,並且每次您想要顯示信息窗口或關於窗口(具有自定義顏色背景和尺寸)時,都可以簡單地創建此類的新實例。

對於簡單的事情,不需要類。 但是對於更復雜的事情,類有時可以使解決方案更容易。

我認為最好的答案是,這取決於縮進對象應該/應該做什么。 但是通常,類和導入的模塊之間存在一些差異,這將使它們在當前模塊中具有不同的功能。 最重要的是,該類已被定義為對象,這意味着它們具有很多選項,可以像模塊所沒有的對象一樣工作。 例如,一些特殊屬性,如__getattr____getattr__ __setattr__ __iter____getattr__ __setattr__等,並且具有創建大量實例甚至控制其創建方式的能力。 但是對於模塊,文檔很好地描述了它們的用例:

如果從Python解釋器退出並再次輸入,則所做的定義(函數和變量)將丟失。 因此,如果要編寫更長的程序,最好使用文本編輯器為解釋器准備輸入,然后使用該文件作為輸入來運行它。 這稱為創建腳本。 隨着程序時間的延長,您可能需要將其拆分為多個文件,以便於維護。 您可能還想使用在多個程序中編寫的便捷功能,而無需將其定義復制到每個程序中。

為此,Python提供了一種將定義放入文件中並在腳本或解釋器的交互式實例中使用它們的方法。 這樣的文件稱為模塊; 可以將模塊中的定義導入其他模塊或主模塊中(您可以在頂層和計算器模式下執行的腳本中訪問的變量集合)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM