簡體   English   中英

導入Python類的說明

[英]Explanation of importing Python classes

所以我知道這可能被認為是一個很寬泛的問題,對此我感到抱歉,但是我在理解整個導入以及__init__self.方面遇到了問題self. 東西等等...我已經嘗試閱讀Python文檔和其他一些教程,但這是我的第一門語言,我有點(很多)困惑。

到目前為止,在我大學的第一學期中,我已經學習了Python的基礎知識,函數,數值類型,序列類型,基本邏輯知識。 但是它的運行速度比我想的要慢,因此我不得不自己嘗試多學一點,並創建一個受Ogame啟發的基於文本,策略,資源管理的基本游戲。

我遇到的第一個問題是如何定義每座建築物,例如每座產生資源的地雷。 我做了一些研究,發現類很有用,所以我對每棟建築物都有這樣的東西:

class metal_mine:

    level = 1

    base_production = 15
    cost_metal = 40
    cost_crystal = 10
    power_use = 10

    def calc_production():
        metal_mine.production = A formula goes here

    def calc_cost_metal():
        etc, same for crystal

    def calc_power_use():
        metal_mine.power_use = blah blah

    def upgrade():
        various things
        solar_plant.calc_available_power()

很長一段時間,我遺漏了很多東西。 無論如何,所以重要的一點是最后一點,當我升級礦山時,要確定礦山是否有足夠的功率運行,我會計算其類別中的太陽能發電廠的功率輸出( solar_plant.calc_output() ),其中包含許多與金屬礦山類相似的東西。 如果我將所有內容都放在同一個模塊中,那么這一切都將非常出色,但是對於許多建築物和研究水平之類的東西來說,它會變得很長,我會迷失其中。

因此,我嘗試將其拆分為不同的模塊,一個模塊用於礦山,一個模塊用於存儲建築物,一個模塊用於研究水平,等等。這使所有事情都變得很整潔,但是我仍然需要一種方法來調用類中的函數,這些函數現在已經屬於一個不同的模塊。 我最初的解決方案是說,例如, from power import * ,這對於大多數情況下,取得了solar_plant在可用類metal_mine類。 我主要說的是,因為根據我嘗試做事的順序,有時候看來這是行不通的。 solar_plant類本身調用了metal_mine類中的變量,現在我知道這已經變得非常意大利式了。.但是我不知道要遵循的更好的約定。

無論如何,有時當我調用solar_plant類,然后又嘗試調用metal_mine類時,它表示metal_mine ,這使我想到需要以某種方式初始化模塊或類? 在代碼中的各個事物之間似乎存在一些循環。 而且,根據我嘗試和“玩游戲”的順序,有時我會無意間這樣做,有時卻沒有。 我還沒有學會導入和重新加載的約定和細節以及所有這些..所以我不知道我是否采用了正確的方法或其他方法。

如果我剛才所說的一切都是合理的,我能否就如何適當地使這些各種模塊的內容免費提供給他人並進行修改提供一些意見? 我是否可能試圖將事情分解為通常不做的不同模塊,而我應該處理大型模塊? 還是我輸入的內容有誤? 要么...?

另外,在大多數教程和地方,我需要尋求幫助,可以看到充滿self.something和init函數的類或函數。我可以對此進行解釋嗎? 還是指向簡單的初學者教程的鏈接?

=================更新=================

好吧,太寬泛了,就像我想的那樣。 根據我得到的幫助,我認為可以縮小范圍。

我整理出來什么,我認為需要的類變量,那些不改變- namebase_cost_metalbase_cost_crystal ,其余全部將取決於當前所選類型的建築物(假定他們可以有多個定居點)的球員。

摘錄一下我現在擁有的內容:

class metal_mine:

    name = 'Metal Mine'

    base_cost_metal = 60
    base_cost_crystal = 15

    def __init__(self):
        self.level = 0
        self.production = 30
        self.cost_metal = 60
        self.cost_crystal = 15
        self.power_use = 0
        self.efficiency = 1

    def calc_production(self):
        self.production = int(30 + (self.efficiency * int(30 * self.level * 1.1 * self.level)))

    def calc_cost_metal(self):
        self.cost_metal = int(metal_mine.base_cost_metal * 1.5 ** self.level)

因此,據我了解,這是一個更正確定義的類? 我用其起始值定義實例變量,然后在用戶播放時對其進行更改。

在我開始游戲的主要功能中,我將創建每個地雷的實例,例如player_metal_mine = metal_mine() ,然后用player_metal_mine = metal_mine()調用所有函數和變量

>>> player_metal_mine.level
0
>>> player_metal_mine.upgrade()
>>> player_metal_mine.level
1

因此,如果定義正確,我現在是否要使用每個建築物的這些新模板導入每個模塊? 並且一旦導入它們並創建了一個實例,所有新實例及其變量是否都包含在主模塊的范圍內(正確的術語?),這意味着不需要新的導入或重新加載嗎?

如果答案是肯定的,我只需要導入,我應該使用哪種方法? 我知道例如只是import mines ,但這意味着我必須使用mines.player_metal_mine.upgrade()來使用它,這比使用from mines import *或更具體地from mines import metal_mine ,盡管最后一個選項意味着我需要從每個模塊中分別導入每個建築物。 因此,就像我說的那樣,是的,我只是導入它,哪種方法是最好的?

==================更新2 ================= (您可能會跳過文字牆,只是閱讀此內容)

因此,我遍歷了所有內容,更正了所有類,似乎所有內容都可以使用from module import *正確from module import * ,但是我在代表資源級別的變量范圍方面遇到問題。

如果所有內容都在1個模塊中,則在頂部,我將聲明每個變量並為其提供起始值,例如metal = 1000 然后,在我班上采用任何改變方法的方法(例如升級建築物,對資源進行成本計算)或在任何改變方法的函數中(例如將所有生產定期添加到當前資源水平的方法),我都將global metal放在例如,在頂部。 然后,在函數內,我可以調用並更改metal的值,這沒有問題。

但是,現在我將這些類和函數從各個模塊中全部導入到1個模塊中,函數無法找到這些變量。 我原本會想到的是,在導入過程中,我基本上會說,將本模塊中的所有內容都裝好,並在本模塊中假裝現在使用它。 但這顯然不是事實。

在我的主模塊中,例如,使用from mines import *導入所有模塊,並將“ metal的值定義為1000 現在,我創建一個金屬礦的實例,“ metal_mine_one = metal_mine()”,然后可以調用其方法和變量,例如

>>> metal_mine_one.production
30

但是,當我嘗試調用諸如metal_mine_one.upgrade()類的方法時,該方法包含global metal ,然后metal -= self.cost_metal ,這給我一個錯誤,提示未定義metal。 就像我說的那樣,如果這是所有模塊中的一個,則不會發生此問題,但是如果我嘗試導入內容,它會發生。

那么,如何以一種不會引起此問題的方式導入這些模塊,並使主模塊的全局范圍內的變量可用於所有導入模塊中的所有函數和方法?

首先是有關面向對象編程的一些背景知識。 即類。 您應該想到一個類似於藍圖的類,它展示了如何制作東西。 當您創建一個類時,它描述了如何為程序創建對象。 python中的一個簡單類可能看起來像這樣。

class foo:
  def __init__(self, bars_starting_value):
    self.bar = bars_starting_value

  def print_bar(self):
    print(self.bar)

這告訴python如何制作foo對象。 初始化函數稱為構造函數。 創建新的foo時會調用它。 自我是引用運行該函數的foo的一種方式。 在這種情況下,每個foo都有自己的bar,可以使用self.bar從foo內部進行訪問。 請注意,必須將一個self作為函數定義的第一個參數,這樣才能使這些函數屬於單個foo而不是全部。

人們可能會像這樣使用此類:

my_foo = foo(15)
my_other_foo = foo(100)
foo.print_bar()
foo.bar = 20
print(foo.bar)
my_other_foo.print_bar()

這將輸出

15
20
100

就進口而言。 它們接受一個文件中定義的所有內容,並將它們移至另一個文件中定義。 如果將類定義放在文件中,則可以將其導入主程序文件並從中創建對象,這很有用。

至於使變量可供其他人使用,您可以將所有發電機產生的功率傳遞給礦山的功能,以確定其是否具有足夠的功率。

希望這可以幫助。

init是一個內置方法,在創建類的實例時會自動調用該方法。 在您提供的代碼中,您已經創建了一個類,現在您需要創建該類的實例。 一個簡單的例子:

class Test:
    def __init__(self):
        print "this is called when you create an instance of this class"
    def a_method(self):
          return True

class_instance = Test()
>>> "this is called when you create an instance of this class"
class_instance.a_method()
>>> True

類方法中的第一個參數始終是*。 按照慣例,我們只稱該參數為“自我”。 您的方法不接受任何參數,請確保它們接受self(或在其上方使用裝飾器@staticmethod)。 另外,請確保您通過self.a_methodclass_instance.a_method引用屬性(在您的情況下為方法)

暫無
暫無

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

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