2013-04-27 45 views
0

我想學習python 3中面向對象的編程。我正在做一個筆記本程序的變體,我在一本書中但不是將筆記添加到筆記本中我正在嘗試將時間添加到時間表。'自我'似乎佔據了我的一個論點

在原來的教程,這是在主程序:

def add_note(self): 
    memo = input("Enter a memo: ") 
    self.notebook.new_note(memo) 
    print("Your note has been added") 

,這是類模塊(筆記本):

def new_note(self, memo, tags = ''): 
    '''create a new note and add it to the list''' 
    self.notes.append(Note(memo,tags='')) 

我的變化是這樣的:

main:

def add_work_day(self): 
     date = input ("Enter date : ") 
     hours = input ("Enter hours worked : ") 
     rate = input ("Enter hourly rate : £") 
     workday = Timesheet.day(date, hours, rate) 

模塊:

class Timesheet: 
     def __init__(self): 
      self.timesheet = [] 

     def day(self, date, hours, rate): 

     self.timesheet.append(day(date, hours, rate)) 

這是給我這個錯誤:

File "C:\Python33\timesheet_menu.py", line 39, in add_work_day 
    workday = Timesheet.day(date, hours, rate) 
TypeError: day() missing 1 required positional argument: 'rate' 

好像在「自我」「高清天(個體經營,日期,時間,速度)」霸佔之一我的輸入參數。

有人能告訴我我在這裏失蹤了嗎?

.....更新.....

所以,現在我已經在主要創建時間表()的一個實例:

def add_work_day(self): 
     date = input ("Enter date : ") 
     hours = input ("Enter hours worked : ") 
     rate = input ("Enter hourly rate : £") 
     workday = Timesheet() 
     workday.add_day(date, hours, rate) 

但我從得到一個新的錯誤我的時間表()方法「天」

class Timesheet: 


    def __init__(self): 
     self.timesheet = [] 

    def day(self, date, hours, rate): 
     self.timesheet.append(day(date, hours, rate)) 

File "C:\Python33\timesheet_menu.py", line 40, in add_work_day 
workday.add_day(date, hours, rate) 
File "C:\Python33\timesheet.py", line 29, in add_day 
self.timesheet.append(day(date, hours, rate)) 
NameError: global name 'day' is not defined 

據我所知,這個問題是.append(一天的一部分,但我無法弄清楚如何解決它。我知道一個變量是不是全球性的,除非規範ified,但我的邏輯告訴我,方法應該是。因此,它必須是.append(天正在尋找所謂的「天」原先存在的變量。我很困惑,因爲這種方法在例如,從書的工作。

+0

在'Timesheet'的'day()'方法內部,你試圖調用'day()',如果你的語法正確的話會導致無限循環。你究竟在做什麼*試圖完成什麼? – rmunn 2013-04-28 16:26:26

+0

是的,我偶然發現了這個無限循環!我現在排序了。我忘記了我有另一個名爲Work_day的類,我應該一直打電話而不是在day()內調用day()。感謝您的親切幫助和耐心! – Dijerydack 2013-04-28 17:29:26

回答

2

問題的根源在於你還不瞭解Python類和實例是如何工作的。

,A級,像Timesheet,是方法(函數)和變量,它們生活在類的命名空間的集合。一個實例是類的一個具體實例(即,時間表,而不是所有存在的其他時間表)。每個實例都有自己的名稱空間,這有點特別:當您在實例名稱空間中查找方法或變量時,如果找不到該名稱,那麼將接下來搜索類名稱空間。 (如果該類繼承自其他類,則會依次搜索其祖先的名稱空間,直到找到該名稱或者沒有更多名稱空間可供搜索爲止。)

現在,方法(函數)定義在類中有一個特殊的行爲,這些函數定義了以外的類沒有 - 這就是爲什麼一個不同的術語(方法)用於類中定義的函數,以幫助提醒你這種特殊的行爲。特殊的行爲是這樣的:如果在該類的實例上調用該函數,那麼該實例將作爲「額外」第一個參數傳遞給該函數。 (按照慣例,第一個參數叫做self,但如果你願意的話,你沒有理由不能稱它爲fhqwhgads。你不應該 - 它會讓你的代碼完全混淆閱讀 - 但是如果你想爲什麼。)爲什麼這額外的第一paremeter?那麼,請記住我如何說實例具有自己的名稱空間?如果你想要查找的實例變量(例如,要查找在的條目這時間表,而不是在那裏的其他時間表),那麼你需要的實例的引用。 self參數提供了該參考。現在

,如果你調用的類的方法,而不是在一個實例,沒有必要額外self參數,因爲你顯然已經有了一個對類的引用:該引用是名稱Timesheet。因此,當您執行Timesheet.day(...)時,在其他參數之前將不會添加「額外」第一個參數。這是因爲你沒有引用實例,而是引用了一個類。

但是,如果你打電話Timesheet().day(...),那麼兩件事情正在發生。首先,您正在創建一個實例TimesheetTimesheet()公式是您如何創建實例),然後您在該實例上調用day()方法。因此,「額外」第一個參數將傳遞給您的day()方法,以便day()內的代碼將能夠訪問該實例的變量。你需要

的另一件事明白:當變量上的一個實例屬於,而當它們屬於一類。有一個很簡單的問題,你可以問自己,以確定這一點:「這並不適用於每時間表,或只具體時間表?」您的day()方法顯然需要訪問特定時間表中的值(Joe的工作時間不同於Bob,薪酬不同),因此您需要在實例上調用它,而不是在課程上。因此,在day()方法中使用self參數是有道理的,但您也需要從方法中調用它,而不是從類中調用它。

所以不是Timesheet.day(...),你應該這樣做:

my_timesheet = Timesheet() 
my_timesheet.day(...) 
# Now do something with the timesheet: calculate total pay, print it out, etc. 
my_timesheet.calculate_total_pay() # Made up example 
my_timesheet.print_to_screen() # Made up example 

這將毫無意義做Timesheet.calculate_total_pay(),因爲總收入中具體的,個別時間表取決於值。所以calculate_total_pay()也應該是一個實例方法,因此應該有一個self參數。實際上,在這種情況下,我沒有提出任何應該叫做Timesheet.some_method()的方法。 (類似這樣的方法在Python中稱爲「靜態方法」,BTW)。我能想到的每一個示例方法都是一種實例方法(即應該在實例上調用的方法,因爲它需要訪問中的數據,該時間表爲)。

有點囉嗦,但我希望這可以幫助你更好地理解類和實例。

+0

感謝這個偉大的解釋。我非常有必要舉一個例子,謝謝! – Dijerydack 2013-04-28 09:34:23

1

變化workday = Timesheet.day(date, hours, rate)workday = Timesheet().day(date, hours, rate)

+0

除非在'Timesheet.day'的末尾添加'return self',否則這將不起作用。 – Blckknght 2013-04-28 02:10:03

+0

這應該是'workday = Timesheet()',後面跟着'workday.day(date,hours,rate)'的第二行。這樣,你仍然擁有「工作日」實例的副本,並且可以在以後使用它來完成其他事情,例如計算總工資。 – rmunn 2013-04-28 04:05:14

0

你遇到的問題是你沒有在你當前的代碼中創建一個Timesheet實例,你只是直接調用一個方法,因爲unbound方法只是函數,你會得到一個參數不匹配的錯誤,因爲沒有self對象被隱式傳遞。

以下是我如何修復代碼:

現在
def add_work_day(self): 
    date = input ("Enter date : ") 
    hours = input ("Enter hours worked : ") 
    rate = input ("Enter hourly rate : £") 

    workday = Timesheet() # create Timesheet instance 
    workday.day(date, hours, rate) # add a workday to it 

    # presumably you'll also want to do something with `workday` here too 

,這可能是因爲你已經在班級的方法是建立在其他什麼地方Timesheet實例。在這種情況下,你只需要參考它(通過self),而不是創建一個新的一個:

def add_work_day(self): 
    date = input ("Enter date : ") 
    hours = input ("Enter hours worked : ") 
    rate = input ("Enter hourly rate : £") 

    self.myTimesheetInstanceCreatedSomewhereElse.day(date, hours, rate) 
相關問題