簡體   English   中英

為什么我的實例計數器在這個 Python 代碼中顯示為 0?

[英]Why is my instance counter display 0 in this Python code?

我編寫了一個簡單的代碼來演示和理解類 - 但是當我運行它時,我的列表顯示它們是空的,包含“無”值而不是用戶作為名稱輸入的字符串。

#Static methods do not require the object to be initiated. Can be remotely accessed from outside the function .

#Counting critters and remote access.

class Orc (object):

    total = 0       

    def get_score (self):
        print "The number of orcs the orc factory has made is",Orc.total   

    def __init__ (self):
        Orc.total += 1
        name =  raw_input ("I am a critter by the name of:\n")


#Creating 10 Orcs 


list = []

for i in range (4):    list[i] = list.append(Orc.get_score(Orc()))  

print "You have created 4 Orcs!" print "The name of your first orc is",list[0] print "The name of your fourth orc is", list[3]

您的代碼中有一些錯誤。 首先是您使用列表的方式。 其次,在您調用對象方法的方式上。 錯誤的組合解釋了為什么最后有一個None列表。

列表名稱

list = []

不要命名列表list 它已經是列表 class 的名稱,即在 Python 中,您可以使用完全相同的效果執行my_list = []my_list = list()

你想給你的列表命名一些有意義的東西,比如orc_list

列表插入

for i in range (4):
    orc_list[i] = orc_list.append(...)

orc_list.append執行它所說的:它將一個元素附加到給定的列表中。 但是,它返回任何內容。 所以你的代碼正在做的是

  1. 取一個空列表
  2. i設置為 0
  3. 在列表末尾插入您傳遞給append的內容
  4. 在索引i處插入None ,從而覆蓋您在 3 中所做的操作。
  5. 遞增i
  6. 回到3。

你想簡單地使用orc_list.append(...)

方法調用

Orc.get_score(Orc())

我想你對self論點感到困惑。 在 class 中,Python 將自動將您正在處理的實例作為self參數傳遞。 你不需要提供那個論點。

你想寫

Orc().get_score()

這將創建一個Orc object,然后對其調用get_score Python 將您創建的Orc實例“注入”到get_score中。

方法返回

我們現在下降到

orc_list.append(Orc().get_score())

這相當於

score = Orc().get_score()
orc_list.append(score)

問題是get_score中沒有return語句。 這意味着當您調用該方法時, python 將返回None 這意味着您將None附加到您的列表中。

你想擁有

def get_score(self):
    print "The number of orcs the orc factory has made is", Orc.total
    return Orc.total

Static 行為

如果你真的想要一個不綁定到Orc class 實例的方法,你可以使用class 方法static 方法

在您的情況下,您不需要對 class object 執行任何操作,因此您的選擇是使用 static 方法。

你會聲明

@staticmethod
def get_score():
    print "The number of orcs the orc factory has made is", Orc.total

然后,您將使用Orc.get_score()調用該方法

要在 Python 中定義 class 方法,請使用classethod裝飾器並調用第一個參數cls

class Orc(object):

    total = 0       

    @classmethod # this will make the method a class method
    def get_score (cls): # convention is then to call the 1st param 'cls'
        print "The number of orcs the orc factory has made is", cls.total   

    def __init__ (self):
        Orc.total += 1
        # use self is you want' to register a name
        # however putting a raw_input in an __init__ is NOT recommanded
        # you should pass name as a parameter 
        # and call the raw_input in the for loop
        self.name =  raw_input ("I am a critter by the name of:\n")

orcs = [] # don't call your lists 'list' because `list` is standard Python function

for i in range(4): # put this on two lines for clarity or use a comprehension list
   orcs.append(Orc())  

print "You have created 4 Orcs!" 
print "The name of your first orc is", orcs[0].name # if you don't use `name`, you will see the reference of the object

print "The name of your fourth orc is", orcs[3].name

更簡潔的版本(你應該瞄准的東西):

class Orc(object):

    total = 0       

    @classmethod # 
    def get_instances_count(cls):
        """
            Return the number or orcs that have been instanciated 
        """
        # ^ Put some documentation below your method
        # these are called "docstring" and are detected by Python

        # you should return values in method rather than print
        # there are rare cases when you do want print, but when you'll
        # encounter them, you won't need me to correct your code anymore
        return cls.total   

    def __init__ (self, name):
        Orc.total += 1
        self.name = name # we get the name as a parameter


l = []

for i in range(4): # put this on two lines for clarity or use a comprehension list
   orc = Orc(raw_input("Enter a name:\n"))
   l.append(orc)  

print "You have created %s Orcs!" % Orc.get_instances_count()
print "The name of your first orc is", l[0].name #

print "The name of your fourth orc is", l[3].name

現在是更 Pythonic 的版本(一旦習慣了 Python,你應該可以做的事情):

class Orc(object):

    total = 0       

    # you don't need accessors in Python: most things are public anyway
    # and you got property

    def __init__ (self, name):
        Orc.total += 1
        self.name = name # we get the name as a parameter

    def __str__(self):
      # this will be call when printing an orc
      return self.name

# list comprehension are quick and clean ways to create lists
# give a real name to your list
orcs = [Orc(raw_input("Enter a name:\n")) for i in range(4)]

# using parenthesis for `print` is a good habit to take with then incoming Python 3
print("You have created %s Orcs!" % Orc.total)
for i, orc in enumerate(orcs):
  print("Orc #%s is %s" % (i, orc))

list.append返回None值,因此將其結果分配給任何東西基本上沒有意義。 您調用append以獲得副作用,即讓它在列表末尾放置一個值。 像這樣:

for i in range (4):    
    list.append(Orc.get_score(Orc()))

我也不認為Orc.get_score(Orc())是您想要的:它還返回None而不是分數,並且方法調用在技術上是正確的,但不太可能是您真正想要的。

為什么你的清單里應該有一些東西?

你做:

list.append(Orc.get_score(Orc())

這相當於:

item_to_add = Orc.get_score(Orc())
list.append(item_to_add)

您的方法Orc.get_score沒有 return 語句,因此它返回None 因此, item_to_add 將為 None,並且 None 將附加到您的列表中。

作為旁注:python 不是 java。 不要僅僅為了使用類而使用類。 當您想遵循 OO-Pradigma 時,使用類,即向對象發送消息。

暫無
暫無

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

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