[英]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
執行它所說的:它將一個元素附加到給定的列表中。 但是,它不返回任何內容。 所以你的代碼正在做的是
i
設置為 0append
的內容i
處插入None
,從而覆蓋您在 3 中所做的操作。i
你想簡單地使用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
如果你真的想要一個不綁定到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.