2017-10-20 125 views
2

我開始使用類來創建一個簡單的觸點輸出開始,然後一個更新的版本是這樣的:(Python的初學者)需要在班

My Contacts 
----------- 
??? Murphy    555-555-8980 
George Smith   555-555-2323 
Mike Johnson   555-555-4780 
----------- 

My Contacts 
----------- 
Cade Murphy    555-555-8980 
President George Smith 555-555-2323 
Professor Mike Johnson 555-555-4780 
---------- 

我具備的功能設置正確,但我不知道要輸入class Contact以便打印出我想要的內容。

class Contact: 
    # I don't know what to put here  

def print_directory(contacts): 
    print("My Contacts") 
    print("-----------") 
    for person in contacts: 
     print(person) 
    print("-----------\n") 


def main(): 
    champ = Contact("???", "Murphy", "555-555-8980") 
    president = Contact("George", "Smith", "555-555-2323") 
    professor = Contact("Mike", "Johnson", "555-555-4780") 

    contacts = [champ, president, professor] 

    print_directory(contacts) 

    champ.set_first_name("Cade") 
    president.set_title("President") 
    professor.set_title("Professor") 

    print_directory(contacts) 


main() 

我試着看教程和類的文檔,但我沒有得到任何地方。任何幫助將不勝感激,謝謝。

+1

鑑於你的打印語句,我假設你使用python3 +。您可以從讀取'class Contact():'的代碼行中刪除'():'。 Contact的參數將是另一個可以擴展屬性或屬性的類。要打印一行,您需要在您的課堂中放置__str__方法。在移動設備上打字,但可以稍後更新。 – mikey

+0

@mikey我覺得你對初學者來說太遙遠了...... –

回答

3

首先,它需要初始化所以把一個__init__函數。

class Contact: 
    def __init__(self, first_name, last_name, phone_number): # Arguments. self is always needed. 
     self.first_name = first_name 
     self.last_name = last_name 
     self.phone_number = phone_number 

那麼這個類有三個變量。 其次,它需要變成一個字符串。

class Contact: 
    def __init__(self, first_name, last_name, phone_number): # Arguments. self is always needed. 
     self.first_name = first_name 
     self.last_name = last_name 
     self.phone_number = phone_number 

    def __str__(self): 
     return "%s %s \t %s" % (self.first_name, self.last_name, self.phone_number) 

你必須在代碼中set_first_name功能,所以要一個

class Contact: 
    def __init__(self, first_name, last_name, phone_number): # Arguments. self is always needed. 
     self.first_name = first_name 
     self.last_name = last_name 
     self.phone_number = phone_number 

    def __str__(self): 
     return "%s %s \t %s" % (self.first_name, self.last_name, self.phone_number) 

    def set_first_name(self, first_name): 
     self.first_name = first_name 

而在去年,你在你的代碼中set_title功能。

class Contact: 
    def __init__(self, first_name, last_name, phone_number): # Arguments. self is always needed. 
     self.first_name = first_name 
     self.last_name = last_name 
     self.phone_number = phone_number 

    def __str__(self): 
     return "%s %s \t %s" % (self.first_name, self.last_name, self.phone_number) 

你必須在代碼中set_first_name功能,所以要一個

class Contact: 
    def __init__(self, first_name, last_name, phone_number): # Arguments. self is always needed. 
     self.first_name = first_name 
     self.last_name = last_name 
     self.phone_number = phone_number 
     self.title = None 

    def __str__(self): 
     if self.title is None: 
      return "%s %s \t %s" % (self.first_name, self.last_name, self.phone_number) 
     else: 
      return "%s %s %s \t %s" % (self.title, self.first_name, self.last_name, self.phone_number) 

    def set_first_name(self, first_name): 
     self.first_name = first_name 

    def set_title(self, title): 
     self.title = title 
+0

太棒了!這有助於我的理解。有沒有辦法讓第二組數字排列起來? –

+1

@MooOnKazoo我正在使用標籤轉義'\ t' –

2

在面向對象編程(OOP)中,類定義了保存相關屬性的對象。

代表你在一個類中的聯繫人將是(你猜對了)使用接觸類,但對於清潔,我們也將有一個電話簿類最簡單的方法:

class Contact: 
    def __init__(self, first_name, last_name, phone_number): 
     # The init method is the one called when you instantiate the class 
     # Ideally it takes all mandatory parameters, that is 
     # Information without which the object would not fulfill its job 

     # We could do other stuff, but here we only save the parameters given 
     # as object properties so you can refer to them later 
     self.first_name = first_name 
     self.last_name = last_name 
     self.phone_number = phone_number 

    def print_info(self): 
     # Ideally a data operation class wouldn't be printing anything 
     # We should return this information as a string and handle it elsewhere 
     # We'll print it right out of the bat though to keep it straightforward 
     print(self.first_name, self.last_name, self.phone_number) 

class Phonebook: 
    def __init__(self): 
     # The phonebooks don't need any special stuff to exist, 
     # so the only parameter taken is the implicit self 
     self.contact_list = [] 

    def add(self, contact): 
     # Here is a method that adds an instance of Contact to the list 
     self.contact_list.append(contact) 
     return self 

    def get_all(self): 
     # Again, IDEALLY this would be what we would call 
     # And this list would be handled elsewhere to be printed... 
     return self.contact_list 

    def print_all(self): 
     # ...however this is a small program, and this class can print itself 
     print("My contacts") 
     print("-----------") 
     for contact in self.contact_list: 
      contact.print_info() 
     print("-----------\n") 

def main(): 

    phonebook = Phonebook() # Phonebook had no __init__, so no params are used 

    # Then we create the contacts (remember the params we defined at __init__) 
    champ = Contact("???", "Murphy", "555-555-8980") 
    president = Contact("George", "Smith", "555-555-2323") 
    professor = Contact("Mike", "Johnson", "555-555-4780") 

    # And we add them to the phonebook (remember method add) 
    # We can chain all .add calls because of the "return self" line 
    phonebook.add(champ).add(president).add(professor) 

    # We can then print everything! 
    phonebook.print_all() 

main() 

編輯

正如已經指出的那樣,Python有一個內置的__str__方法,我們不需要定義print_info()。我沒有改變我的代碼塊,因爲我想明確地解釋方法會對初學者更好。儘管如此,更合適的方法是定義__str__,然後定義print(contact)而不是調用contact.print_info()

+2

怎麼樣,而不是'print_info',用__str__'去掉 – 0TTT0

+1

好點,雖然OP似乎並不習慣OOP,更多與語言無關的方式(我所做的)也是有效的。我會編輯這個。 – gchiconi

3

,如果你只想設置屬性:

professor.first_name = "Mike" 

這將增加一個屬性first_name,其價值是Mike,動態

如果你需要一個二傳手,使其OO更多:

class Contact(object): 

    def set_first_name(self, fn): 
     self._first_name = fn 

professor.set_first_name(Mike) 

您可能需要使用__init__,在類的構造函數,這使得它更加OO:

class Contact(object): 

    def __init__(self, first_name, last_name, tel): 
     # convention: private members' name usually start with '_' 
     self._first_name = first_name 
     self._last_name = last_name 
     self._tel = tel 

那麼你可以使用:

professor = Contact("Mike", "Johnson", "555-555-4780") 

如果您想了解更多Python的面向對象,你可以使用設定器/吸氣劑裝飾:

類聯繫(對象):

@property 
def first_name(): 
    # this is a getter 
    print "getter!" 
    return self._first_name 

@first_name.setter 
def first_name(self, first_name): 
    # this is a setter 
    print "setter!" 
    self._first_name = first_name 

您可以:

professor = Contact() 
professor.first_name = "Mike" # this calls the setter, set value of `_first_name` 
print(professor.first_name) # this calls the getter, return value of `_first_name` 

注:這是Python中的約定名稱的私有成員與_開始,像_first_name。這提示外層不應該直接操作這個成員。

希望這會有所幫助。

小更新: 我想在Python中,Contact一個list表示電話簿足以在大多數情況下,包括情況下,當你需要使用一些ORM/ODM LIB將其寫入到數據庫中。無需PhoneBook課程。只是我的想法。

小更新2: 有人說在回答和評論__str__,這是一個很好的觀點。見@Bryan Zeng的回答。還有一種叫做__repr__的東西提供了與__str__類似的功能。

這個問題可能幫助:Difference between __str__ and __repr__ in Python

我推薦一本書「流利蟒」,它推出了很多的「神奇功能」(函數開始和結束與線下雙)於二OO一章,這將在Python OO編程中提供了很大的幫助。

小更新3:修復setter/getter裝飾器上的錯誤。我沒有使用它一段時間,我寫錯了... @setter應該是@first_name.setter。爲此事道歉。

+0

你的答案更多Pythonic。在我開始把所有的東西都變得如此簡單之前,我需要將JS原型從我的腦海中取出...... – gchiconi

+1

我從「Fluent Python」一書的OO章節中學到了這些「魔術功能」,真正值得Python愛好者閱讀。 – raaay0608

+0

@ raaay0608喜歡'__str__'和'__add__'等等 –