簡體   English   中英

在Python中跟蹤類實例變量的好方法是什么?

[英]What's a good way to keep track of class instance variables in Python?

我是一名剛開始學習Python的C ++程序員。 我想知道如何在大型Python類中跟蹤實例變量。 我習慣有一個.h文件,它給了我一個整齊的列表(包括評論)所有類的成員。 但是,由於Python允許您動態添加新的實例變量,您如何跟蹤它們?

我正在想象一個場景,當我已經有一個新的實例變量時,我錯誤地添加了一個新的實例變量 - 但它離我工作的地方有1000行。 是否有避免這種情況的標准做法?

編輯:看起來我對術語“成員變量”產生了一些困惑。 我的意思是實例變量,我已經相應地編輯了我的問題。

我想說,避免這種情況的標准做法是不要寫類,你可以在1000行以外的任何地方!

說真的,對於任何有用的類來說,這太過分了,特別是在與Python一樣富有表現力的語言中。 使用標准庫提供的更多內容並將代碼抽象到單獨的模塊中應該有助於保持LOC的倒計時。

標准庫中最大的類別遠低於100行!

首先:類屬性還是實例屬性? 或兩者? =)

通常,您只需在__init__添加實例屬性,在類定義中添加類屬性,通常在方法定義之前...這應該涵蓋90%的用例。

如果代碼動態添加屬性,它可能(希望:-)有充分的理由這樣做......利用動態特性,內省等。除此之外,以這種方式添加屬性可能不像你想象的那么常見。

實例變量應該在類的__init__()方法中初始化。 (一般來說)

如果那是不可能的。 您可以使用__dict__在運行時獲取對象的所有實例變量的字典。 如果您真的需要在文檔中跟蹤它,請將您正在使用的實例變量列表添加到類的docstring中。

pylint可以靜態檢測__init__中未檢測到的屬性,以及許多其他潛在的錯誤。

我還建議編寫單元測試並經常運行代碼來檢測這些類型的“whoopsie”編程錯誤。

聽起來你在談論實例變量而不是類變量。 請注意,在以下代碼中,a是類變量,b是實例變量。

class foo:
  a = 0 #class variable

  def __init__(self):
    self.b = 0 #instance variable

關於你在哪里創建一個不需要的實例變量的假設,因為另一個是大約一千行;最好的解決方案是不要有一千行長的類。 如果你無法避免長度,那么你的課程應該有一個明確的目的,這將使你能夠立刻保持頭腦中的所有復雜性。

文件生成系統(如Epydoc)可用作對象具有的實例/類變量的參考,如果您擔心通過拼寫錯誤意外創建新變量,則可以使用PyChecker檢查代碼。

這是我從許多程序員那里聽到的一個常見問題,他們來自C,C ++或其他靜態類型語言,其中變量是預先聲明的。 事實上,當我們說服我們組織的程序員放棄C用於高級程序並使用Python時,這是我們聽到的最大問題之一。

理論上,是的,您可以隨時向對象添加實例變量。 是的,它可能發生在拼寫錯誤等。實際上,它很少會導致錯誤。 當它發生時,通常不難發現錯誤。

只要你的類沒有膨脹(1000行是非常巨大的!)並且你有足夠的單元測試,你應該很少遇到真正的問題。 如果你這樣做,幾乎可以隨時放到Python控制台,並根據需要檢查事物。

在我看來,這里的主要問題是當你在python中工作時,你正在思考C ++。

擁有一個1000行的類在python中不是一個非常明智的東西,(我知道它在C ++中有很多發生),

學習利用python為您提供的動力,例如,您可以以非常有創意的方式組合列表和詞典,並為您自己保存數百個無用的代碼行。

例如,如果要將字符串映射到函數(用於調度),則可以利用函數是第一類對象並具有如下字典的事實:

d = {'command1' : func1, 'command2': func2, 'command3' : func3}
#then somewhere else use this list to dispatch
#given a string `str`
func = d[str]
func() #call the function!

在C ++中這樣的東西會占用很多行代碼!

最簡單的方法是使用IDE。 PyDev是eclipse的插件。

我不是所有方式pythonic的專家,但一般來說我在python的類定義下定義我的類成員,所以如果我添加成員,他們都是相對的。

我個人認為,由於這個特殊原因,應該在一個部分宣布集體成員。

本地范圍的變量otoh應該被定義為最接近它們的時候(C中除外 - 我認為仍然需要在方法的開頭聲明變量)。

考慮使用插槽

例如:

class Foo:
     __slots__ = "a b c".split()
   x = Foo()
   x.a =1    # ok
   x.b =1    # ok
   x.c =1    # ok
   x.bb = 1  # will raise "AttributeError: Foo instance has no attribute 'bb'"

它通常是任何動態編程語言中的一個問題 - 任何不需要變量聲明的語言 - 變量名中的拼寫錯誤會創建一個新變量而不是引發異常或導致編譯時錯誤。 插槽有助於實例變量,但對模塊范圍變量,全局變量,局部變量等沒有幫助。對此沒有靈丹妙葯; 這是不必申報變量的權衡的一部分。

暫無
暫無

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

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