1
回答
一个python小项目中发现一个不理解的地方,求指导?
极速云服务器,低至1.04元/天>>>   
这是《python基础教程》后面的一个实例项目,我不明白为什么后面ChatSession
类中的enter方法,用room类做参数,但是方法里面又出现了self.room,
这里self.room到底指什么呢,类中并没有room这个属性和方法啊?
from asyncore import dispatcher
from asynchat import async_chat
import socket, asyncore

PORT = 5005
NAME = 'TestChat'

class EndSession(Exception):pass

class CommandHandler:

        def unknown(self, session, cmd):
                session.push('Unknown command: %s\r\n' % cmd)

        def handle(self, session, line):
                if not line.strip(): return

                parts = line.split(' ',1)
                cmd = parts[0]
                try: line = parts[1].strip()
                except IndexError: line = ''

                meth = getattr(self, 'do_'+cmd, None)

                try:
                        meth(session, line)
                except TypeError:
                        self.unknown(session,cmd)

class Room(CommandHandler):

        def __init__(self, server):
                self.server = server
                self.sessions = []

        def add(self, session):
                self.sessions.append(session)

        def remove(self, session):
                self.sessions.remove(session)

        def broadcast(self, line):
                for session in self.sessions:
                        session.push(line)

        def do_logout(self, session, line):
                raise EndSession

class LoginRoom(Room):

        def add(self,session):
                Room.add(self,session)

                self.broadcast('Welcome to %s\r\n' % self.server.name)

        def unknown(self, session, cmd):
                session.push('Please log in \nUse "login"\r\n')

        def do_login(self, session, line):
                name = line.strip()

                if not name:
                        session.push('Please enter a name\r\n')
                elif name in self.server.users:
                        session.push('The name "%s" is taken.\r\n' % name)
                        sessoin.push('Please try again.\r\n')
                else:
                        session.name = name
                        session.enter(self.server.main_room)

class ChatRoom(Room):

        def add(self, session):
                self.broadcast(session.name + ' has entered the room.\r\n')
                self.server.users[session.name] = session
                Room.add(self, session)

        def remove(self, session):
                Room.remove(self, session)

                self.broadcast(session.name + ' has left the room.\r\n')

        def do_say(self, session, line):
                self.broadcast(session.name + ': ' + line + '\r\n')

        def do_look(self, session, line):
                session.push('The following are in this room:\r\n')
                for other in self.sessions:
                        session.push(other.name + '\r\n')

        def do_who(self, session, line):
                session.push('The following are logged in:\r\n')
                for name in self.server.users:
                        session.push(name + '\r\n')

class LogoutRoom(Room):

        def add(self, session):
                try: del self.server.users[session.name]
                except KeyError: pass

class ChatSession(async_chat):

        def __init__(self, server, sock):
                async_chat.__init__(self,sock)
                self.server = server
                self.set_terminator('\r\n')
                self.data = []
                self.name = None

                self.enter(LoginRoom(server))

        def enter(self, room):

                try: 
                        cur = self.room
                except AttributeError: 
                        pass
                else: cur.remove(self)
                self.room = room
                room.add(self)

        def collect_incoming_data(self, data):
                self.data.append(data)

        def found_terminator(self):
                line = ''.join(self.data)
                self.data = []
                try: self.room.handle(self, line)
                except EndSession:
                        self.handle_close()

        def handle_close(self):
                async_chat.handle_close(self)
                self.enter(LogoutRoom(self.server))

class ChatServer(dispatcher):

        def __init__(self, port, name):
                dispatcher.__init__(self)
                self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
                self.bind(('',port))
                self.listen(5)
                self.name = name
                self.users = {}
                self.main_room = ChatRoom(self)

        def handle_accept(self):
                conn, addr = self.accept()
                ChatSession(self,conn)

if __name__ == '__main__':
        s = ChatServer(PORT, NAME)
        try: asyncore.loop()
        except KeyboardInterrupt: print
举报
hyperion000
发帖于2年前 1回/403阅
顶部