2014-09-04 38 views
-1

我正在使用「更多Python編程初學者」一書,並從中複製代碼。嘗試在OOP類中執行某個函數時發生錯誤

我想創建一個函數,在屏幕上用print_text()的屏幕創建文本,並帶有一些渲染文本所需的參數。

下面是函數:

def print_text(font, x, y, text, colour=(255, 255, 255), shadow=True): 
    if shadow: 
     txtimg = font.render(text, True, (0,0,0)) 
     surface.blit(txtimg, (x-2,y-2)) 
    txtimg = font.render(text, True, colour) 
    surface.blit(txtimg, (x, y)) 

這裏是整個程序:

# Trivia Game 
# 
# An editable quiz. Accumulate ALL the points. 
# This has 11 questions so far. 
# 
# ------------------------------------------------- 

import pygame, sys 
from pygame.locals import * 

class Trivia(object): 
    def __init__(self, filename): 
     self.data = [] 
     self.current = 0 
     self.total = 0 
     self.correct = 0 
     self.score = 0 
     self.scored = False 
     self.failed = False 
     self.wronganswer = 0 
     self.colour = [white, white, white, white] 

     txt = open("trivia.txt", "r") 
     tdata = txt.readlines() 
     txt.close() 

     for text_line in tdata: 
      self.data.append(text_line.strip()) 
      self.total += 1 

    def print_text(font, x, y, text, colour=(255, 255, 255), shadow=True): 
     if shadow: 
      txtimg = font.render(text, True, (0,0,0)) 
      surface.blit(txtimg, (x-2,y-2)) 
     txtimg = font.render(text, True, colour) 
     surface.blit(txtimg, (x, y)) 

    def show_question(self): 
     trivia.print_text(font1, 210, 5, "TRIVIA GAME") 
     print_text(font2, 192, 500-20, "press keys 1,2,3,4 to answer", blue) 
     print_text(font2, 530, 5, "SCORE:", blue) 
     print_text(font2, 550, 25, str(self.score), blue) 

     self.correct = int(self.data[self.current+5]) 

     question = self.current // 6 + 1 
     print_text(font1, 5, 80, "QUESTION " + str(question)) 
     print_text(font2, 20, 120, self.data[self.current], white) 

     if self.scored: 
      self.colour = [white, white, white, white] 
      self.colour[self.correct-1] = green 
      print_text(font1, 230, 380, "CORRECT!", green) 
      print_text(font2, 170, 420, "Press Enter For Next Question", green) 
     elif self.failed: 
      self.colour = [white, white, white, white] 
      self.colour[self.wronganswer-1] = red 
      self.colour[self.correct-1] = green 
      print_text(font1, 230, 380, "INCORRECT!", red) 
      print_text(font2, 170, 420, "Press Enter For Next Question", red) 

     print_text(font1, 5, 170, "ANSWERS") 
     print_text(font2, 20, 210, "1 - " + self.data[self.current+1], self.colour[0]) 
     print_text(font2, 20, 240, "2 - " + self.data[self.current+2], self.colour[1]) 
     print_text(font2, 20, 270, "3 - " + self.data[self.current+3], self.colour[2]) 
     print_text(font2, 20, 300, "4 - " + self.data[self.current+4], self.colour[3]) 

    def handle_input(self,number): 
     if not self.scored and not self.failed: 
      if number == self.correct: 
       self.scored = True 
       self.score += 1 
      else: 
       self.failed = True 
       self.wronganswer = number 

    def next_question(self): 
     if self.scored or self.failed: 
      self.scored = False 
      self.failed = False 
      self.correct = 0 
      self.colour = [white, white, white, white] 
      self.current += 6 
      if self.current >= self.total: 
       self.current = 0 

# main program 

pygame.init() 

surface = pygame.display.set_mode((600, 500)) 
pygame.display.set_caption("School") 

font1 = pygame.font.Font(None, 40) 
font2 = pygame.font.Font(None, 24) 

white = 255, 255, 255 
blue = 0, 0, 255 
green = 0, 255, 0 
red = 255, 0, 0 
black = 0, 0, 0 

trivia = Trivia("trivia_data.txt") 

# loop 

while True: 
    for event in pygame.event.get(): 
     if event.type == QUIT: 
      sys.exit() 
     elif event.type == KEYUP: 
      if event.key == pygame.K_ESCAPE: 
       sys.exit() 
      elif event.key == pygame.K_1: 
       trivia.handle_input(1) 
      elif event.key == pygame.K_2: 
       trivia.handle_input(2) 
      elif event.key == pygame.K_3: 
       trivia.handle_input(3) 
      elif event.key == pygame.K_4: 
       trivia.handle_input(4) 
      elif event.key == pygame.K_RETURN: 
       trivia.next_question() 

    surface.fill((black)) 
    trivia.show_question() 

    pygame.display.update() 

我得到運行該程序時的錯誤是:

Traceback (most recent call last): 
    File "C:\Users\PylonBuffering\Desktop\Pylon Buffering\Games\Other\Trivia Game\Trivia Game.pyw", line 126, in <module> 
    trivia.show_question() 
    File "C:\Users\PylonBuffering\Desktop\Pylon Buffering\Games\Other\Trivia Game\Trivia Game.pyw", line 39, in show_question 
    trivia.print_text(font1, 210, 5, "TRIVIA GAME") 
    File "C:\Users\PylonBuffering\Desktop\Pylon Buffering\Games\Other\Trivia Game\Trivia Game.pyw", line 33, in print_text 
    txtimg = font.render(text, True, (0,0,0)) 
AttributeError: 'Trivia' object has no attribute 'render' 

幫助我。如果你發現這個話題已經解決了,請把它和我聯繫起來。

+1

print_text蟒蛇應該有第一個參數的自我。當您將方法作爲對象的屬性調用時,它會自動添加到參數列表中:trivia.print_text(...) - > Trivia.print_text(trivia,...) – mdurant 2014-09-04 18:56:52

回答

1

這是因爲你不具備加self參數print_text。如果你調用一個方法(如「屬於一個類的函數」),傳遞給函數的第一個參數總是實例本身,而不管它的名字。因此,如果您撥打trivia.print_text(font1, ...),參數font將自動變爲trivia的值,x的值將變爲font1等等。

要驗證你的自我試試這個:

class Test: 
    def func(): 
     print "test" 

test = Test() 
test.func() 

這將提高:

TypeError: func() takes no arguments (1 given) 

的參數func獲取傳遞是實例test。 Python會將test.func()「轉換」爲Test.func(test)

另一個問題是,你打電話print_textshow_question沒有自我的前綴。這種方式python不會找到print_text,因爲該函數不在名稱空間中。

您不應該在班級內撥打trivia,而應該使用self(請參閱show_question第1行)。

因此,有三個選項:

  • 添加selffont
  • 移動print_text出類的背景下(dont't所有print_text調用之前忘了實例(selftrivia)前綴)(刪除所有實例前綴(selftrivia),然後調用print_text
  • 添加裝飾器@staticmethodprint_text,this prev經濟需求從傳遞實例作爲參數(不要忘記所有print_text調用之前實例(selftrivia)前綴)
+0

whoops -_-這本書已經把我搞砸了好幾遍了,這對我有幫助 – PylonBuffering 2014-09-06 13:27:24

1

問題是您聲明功能print_text作爲Trivia類的方法。你實際需要的是在全球範圍內宣佈它。

爲了解決這個問題,從這裏移動print_text功能出Trivia類:

 self.total += 1 # Do not move this line. I have only provided it for context 

def print_text(font, x, y, text, colour=(255, 255, 255), shadow=True): 
    if shadow: 
     txtimg = font.render(text, True, (0,0,0)) 
     surface.blit(txtimg, (x-2,y-2)) 
    txtimg = font.render(text, True, colour) 
    surface.blit(txtimg, (x, y)) 

def show_question(self): # Do not move this line. I have only provided it for context 

...到這裏:

black = 0, 0, 0 # Do not move this line. I have only provided it for context 

def print_text(font, x, y, text, colour=(255, 255, 255), shadow=True): 
    if shadow: 
     txtimg = font.render(text, True, (0,0,0)) 
     surface.blit(txtimg, (x-2,y-2)) 
    txtimg = font.render(text, True, colour) 
    surface.blit(txtimg, (x, y)) 

trivia = Trivia("trivia_data.txt") # Do not move this line. I have only provided it for context 
+0

您的答案也有幫助,謝謝:D – PylonBuffering 2014-09-06 13:30:37

相關問題