2015-03-07 5 views
0

У меня проблема с этой мини-игрой, которую я создал, которую я пытаюсь добавить на сервер. .SocketServer AttributeError: экземпляр не имеет атрибута 'request'

Я пытаюсь напечатать функцию из экземпляра символа, но я не знаю, как передать надлежащую функцию в Это то, что я есть:

class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler): 
    Class Character(): 
    name = "" 
    age = 0 

    Class Human(Character): 
    locationX = 0 
    locationY = 0 
    def help(self): 
     self.request.send("Q to Quit") 

    class Boy(Character, Human): 
    def __init__(self, name): 
     self.name = name 
     age = 10 

    def handle(self): 
    p1 = self.Boy("Jim") 

    self.request.send(":") 
    command = self.request.recv(1024).strip() 
    if command == "help": 
     p1.help() 

Моя ошибка:

File "/usr/lib/python2.7/SocketServer.py", line 649, in __init__ 
     self.handle() 
    File "rpg.py", line 281, in handle 
     p1.help() 
    File "rpg.py", line 23, in help 
     self.request.send("Q to Quit") 
    AttributeError: Boy instance has no attribute 'request' 

Может кто-нибудь объяснить, почему это неправильно? Я все еще изучаю Python и Sockets, поэтому, пожалуйста, со мной.

ответ

0

Вы выбрали, чтобы ваши классы Character & гр внедренного в классе ThreadedTCPRequestHandler - но внедренный сильно отличаются от , полученных из. Вложенные классы не имеют специального доступа к self класса, в который они встроены!

Так что вам нужно, чтобы обогатить, например, Character с __init__, который принимает handler экземпляр его создания:

class Character(): 
     def __init__(self, handler): 
      self.name = "" 
      self.age = 0 
      self.handler = handler 

(я также воспользовался возможностью, чтобы сделать имя и возраст экземпляра переменные, что делает более смысл и изменить отступы на стандартные 4 символа против 2, которые вы использовали :-).

Подклассы должны затем вызвать базового класса __init__ соответственно:

class Boy(Character, Human): 
     def __init__(self, name, handler): 
      Character.__init__(self, handler) 
      self.name = name 
      self.age = 10 

и создание новых экземпляров также должны идти вместе:

def handle(self): 
     p1 = self.Boy("Jim", handler=self) 
     # etc etc 

(handler= часть здесь просто для наглядности и читаемости , а не строго для функциональности :-).

Общая архитектура теперь свойственно (встроенные классы редко используются в Python), но по крайней мере это будет работать! -)

+0

Вау, спасибо! Это имеет больше смысла. Еще один вопрос, если внедренные классы редко используются, как можно создать одно и то же, но без встроенного? Должен ли я иметь все за пределами ThreadedHandler? Просто просите о будущем. – 12vi6

+1

Вы переместили бы все встроенные операторы 'class' за пределы инструкции' class ThreadedHandler' и потеряли 'self.' в' p1 = self.Boy («Jim», self) '. Наличие классов «снаружи» позволяет намного легче писать модульные тесты для вашего кода, а сложные тесты на уровне больше, чем «лучшая практика», они являются ** только ** практикой, которую вы должны * когда-либо рассматривать!) –

Смежные вопросы