2012-03-17 94 views
3

我已經做了一個簡單的測試程序來使用類進行實驗。它創建了一個「人」類,它接受了名稱和年齡的論點。我現在正在嘗試創建一個交互式程序,允許用戶管理一個人員列表,如註冊表或通訊簿。他們可以創建一個新的人,如下面的功能所示。Python:將函數結果/變量的值賦給一個類

def createnew(): 
    newname = input("What is their name?") 
    newage = input("How old are they?") 

    newperson = Person(newname, newage) 

當然,上面的問題是,它的字面意思是分配newname,而不是字符串值「newname」。所以我試了

newperson.lower() = Person(newname, newage) 
str(newperson) = Person(newname, newage) 
newperson[0:] = Person(newname, newage) 

但是他們都返回錯誤,不能分配給函數調用。 我的問題是如何訪問變量newname的值並將其分配給Person或任何其他類。

注:我是一個n00b/newb,這意味着我不是來自另一種語言,並且正在閱讀一本書。如果他們不是很明顯,請解釋給出的答案。

很多謝謝。

它弄得有一點更清晰,我試圖讓新的人的名字對象名稱,用戶輸入的值(在我的例子是newperson)

更新:

感謝所有答案,我認爲允許用戶設置變量名稱並不是一個好主意,所以我重新調整了我的代碼。我創建了一個字典,在用戶創建新人之後,將類str函數給出的數據寫入給定名稱的鍵。雖然這意味着我以後不能訪問該對象,因爲新人將被覆蓋,它允許我用一組數據創建一個列表,這是我想要做的第一個地方,我只是錯誤地認爲設置對象名稱會更容易。 再次感謝。

+0

你使用Python 2或Python 3? – imm 2012-03-17 17:58:18

回答

5

如果我正確地理解了你,你想要的是創建Person對象,然後創建一個全局變量,其名稱就是這個人的名字。

這很糟糕。

你真正想要的是一種方法來存儲人物對象,並在以後用他們的名字檢索它們。因此,使用字典:

people = {} 

def createnew(): 
    ... 
    people[newname] = Person(newname, newage) 

後來的後來,你可以訪問該人在詞典:

print(people['name of the person']) 

(我假設你使用Python 3,由於您使用如Python 2中的input()而不是raw_input()。X)

如果你真的必須創建一個新的變量(這是不好的,因爲人的名字通常不是有效的Python標識符),使用globals()功能:

>>> globals()['foo'] = 2 
>>> foo 
2 

但我包括這對爲了完整性。不要使用這個!

+3

@ user1276048,你不想這樣做。不,認真。不要這樣做。永遠不要這樣做。在任何情況下,您都不應該試圖將用戶輸入用作變量的名稱。這個答案是你嘗試去做的正確方法。 – 2012-03-17 18:53:42

+2

@ user1276048:是的,這就是寫這個答案的人認爲你的意思。這不是一個好主意。它使你的生活變得複雜。您需要區分作爲程序員的您如何考慮用戶對數據的看法。創建了新的Person後,您需要知道它是什麼,才能編寫更多使用它的代碼。如果用戶在控制變量名稱,你有點卡住了。用戶的信息已存儲在對象中。您不需要將其反映在變量名稱中。 **這不是**的變數。 – 2012-03-17 20:41:09

1

你使用Python 2還是Python 3?我在猜測,也許你的書是爲Python 3編寫的,而且你正在使用Python 2.我認爲你的第一個程序應該在Python 3中工作,但在Python 2中,input函數可能不會達到你期望的效果。 raw_input功能會更好。讓我知道你正在使用哪個版本的Python,我會盡力給你更具體的幫助。每次啓動Python解釋器或在命令行運行python -V時,都應該看到版本號。

這是你的代碼的版本應該在Python 2工作:

def createnew(): 
    newname = raw_input("What is their name?") 
    newage = int(raw_input("How old are they?")) 

    person = Person(newname, newage) 

我改變inputraw_input。正如下面的voithos建議的那樣,我使用「int」函數將輸入(使用字符串)轉換爲整數。我還更改了最後一行以將Person實例存儲在一個新變量person而不是newname中,因爲對於兩種不同類型的值重複使用相同變量可能會相當混淆。


原因input爲您提供了令人驚訝的結果,如果你檢查的文檔,該功能變得清晰:

http://docs.python.org/library/functions.html#input

它讀取輸入,然後嘗試將其評估爲Python表達式!當你輸入一個名字時,你會得到一個錯誤,因爲它不是一個變量名。因爲這非常令人驚訝,並且通常不是你真正想要的,所以在Python 3中它改變了它,但這確實意味着Python 2和Python 3的書籍和教程需要不同,並且本身可能會導致一些混淆。

+0

更確切地說,在Python 2中'raw_input()'抓取輸入的_string_表示,而不修改它(因此是「原始」)。另一方面,'input()'基本上等同於'eval(raw_input())',這意味着它試圖將字符串評估爲Python表達式。所以,如果輸入是像'31'這樣的數字,那麼'input()'會返回一個int。如果它是'5.4'的東西,它會返回一個浮點數等。它通常更具可讀性並且不易出錯,只是手動轉換類型,la'int(raw_input())' – voithos 2012-03-17 18:07:29

+0

我不認爲我做了我自己很清楚,我試圖用分配給newname的值作爲這個類的名字。因此,如果我將Bob作爲輸入的名稱,它將創建Bob作爲Person類的對象。 – user1276048 2012-03-17 18:38:13

0

我不完全確定問題是什麼,但是您顯示的代碼有一些不一致之處。

  • newname是一個string對象的引用,那麼你在最後一行綁定這個參照Person對象。這是糟糕的設計,因爲它會讓讀者感到困惑。最好打電話給你的Person物品,例如newPerson = Person(...)
  • newname.lower()調用newname對象的lower()功能 - 如果newname仍然是一個string,將工作,但現在它是一個Person。您是否在Person類中定義了def lower(self)成員函數?這個班怎麼樣?
  • str(newname)是一個noop如果newname仍然是string。如果它是一個Person對象,則必須定義一個def __str__(self)成員函數,該函數返回Person的字符串表示形式。

所有的一切我不能確定你真正想要的,但一個人的類可能是這樣的:

class Person(object): 
    def __init__(self): 
     self.name=raw_input("What is their name? ").capitalize() 
     self.age=int(raw_input("How old are they? ")) 

    def __str__(self): 
     return "My name is %s and I'm %d years of age." % (
      self.name, self.age) 

用法:

p=Person() 
print p 

旁註:這可能是糟糕的設計使用raw_input裏面的__init__,和__str__功能可能會更好地返回Person(name=%s, age=%d) % ...,但這只是一個例子,它是如何作品。

+0

我認爲我沒有把自己說得很清楚,我試圖用分配給newname的值作爲班級的名字。因此,如果我將Bob作爲輸入的名稱,它將創建Bob作爲Person類的對象。感謝你的例子,但我已經有了類似的例子。 – user1276048 2012-03-17 18:39:38

0

所有這些函數調用都會返回值而不是變量,所以它們不能被修改。用數學術語來說,就像試圖說2 = 7 + 4。由於2不是一個變量,並且不能真正地以這種方式進行分配/改變,所以這樣做並不合理,而且這位可憐的口譯員正在給你一個悲哀的求助呼籲。另一方面,您可能已經知道,變量可以以x = 7 + 4的形式分配。更改變量x中包含的值是完全正確的,因爲變量包含值,但試圖更改的值,但是另一個值是不可能的。

你需要做的是找到你想改變的變量,把它放在等號的左邊,並把你想要賦值的值放在右邊。當你說Person(newname, newage),你正在創建一個值,在這種情況下一個對象,需要被分配給一個變量,因此可以保持,後來,而不只是丟棄立即使用:

def createnew(): 
    newname = input("What is their name?") #remember to indent these if you want them 
    newage = input("How old are they?") #to be part of the function! 
    newPerson = Person(newname, newage) 
    return newPerson 

現在newPerson包含您剛剛創建的人的價值,您可以訪問其中的變量併爲其賦值,就像其他變量一樣。爲了做到這一點,你需要知道所使用的變量的名稱,這是在你寫的構造函數定義,可能看起來是這樣的:

class Person: 
    def __init__(self, name, age): 
     self.name = name  #the variable that contains the person's name is called 'name' 
     self.age = age  #the variable that contains the person's age is called 'age' 

def createnew(): 
    newname = input("What is their name?") #remember to indent these if you want them 
    newage = input("How old are they?") #to be part of the function! 
    newPerson = Person(newname, newage) 
    return newPerson 

newperson = createnew() #will prompt you to enter name and age for this person and assign them 

print("person's old name: " + newperson.name)  
newperson.name = input("What's is their new name?") #second thought, you want to change Bob's name 
print("person's new name: " + newperson.name) 
+0

我認爲你比大多數人更瞭解我想要的東西,但是有沒有辦法讓用戶可以分配類對象名thingy,在你的例子中它是新人。那就是我一直在努力去做的事情。 – user1276048 2012-03-17 18:40:58

+0

當你說newperson = Person(newname,newage) – user1276048 2012-03-17 18:49:56

+0

@ user1276048時,我該如何讓用戶設置什麼「新人」?如果你正在接觸變量的名字,最終用戶無法控制它。當程序被解釋/運行時,組成變量名稱的所有文本都將被擦除並轉換爲內存中的地址。變量的名稱只是一個簡寫,所以程序員可以參考它轉換的地址和存儲在其中的值。你不能改變變量的名字,但你可以存儲它們的值並根據需要檢索它們,這可能是你真正想要做的。 :d – 2012-03-19 00:57:14