Vererbung - Funktionen überschreiben

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Nicht_zu_definieren
User
Beiträge: 21
Registriert: Freitag 21. April 2006, 17:01
Kontaktdaten:

Freitag 21. April 2006, 17:23

Hallo erstmal.

Ich bin noch relativ neu in der Materie Python, aber kein Voll-Anfänger im programmieren.

Normalerweise, wenn ich in einer Subklasse ein Objekt aus der Hauptklasse neu definiere, dann funktioniert dies wunderbar, und beim aufrufen wird das neue objekt aufgerufen...
Im folgenden Script allerdings nicht, ich entdecke den Fehler auch nicht...

Code: Alles auswählen

class IRC:
import sys
import socket

from time import sleep

debug = 1               #Set to 1 and you see all traffic between server&client
show_ping_pong = 1      #Set to 1 and you see the PING/PONG...

class IRC:
	"""A very low-level implementation of the IRC-Protocol.
	It just supports sending raw commands and receiving everything ;)
	It is used as a base class, to subclass the IRCClient...
	
	"""
	def __init__(self, conn_data, nick):
		"""Connects to the server... :-)
		Starts to handle every receiving message forever.
		"""
		#Define the vars more generally...
		self.conn_data = conn_data
		self.nick = nick
		self.ident = nick
		self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		self.sock.connect(conn_data)
		msg = self.handler()
		msg = self.handler()
		msg = self.handler()
		print 'Sending NICK/USER'
		self.send('/notice B01CC68F nospoof')
		self.send('NICK %s' %(nick, ))
		self.send('USER %s %s %s :%s' %(nick, conn_data[0], nick, 'hu8-IRCBOT'))
		self.send('/notice B01CC68F nospoof')
		self.send('JOIN :#kapiland')
		

	def send(self, msg):
		"""Send the message msg to the server, and adds if necessary the \r\n"""
		if debug == 1:
			print 'OUTPUT==>%s' %(msg, )
		if msg[-1] != 'n' or msg[-2] != '\\':
			msg = msg.__add__('\r\n')
		try:
			self.sock.send(msg)
		except:
			print 'Can not send message: %s' %(msg, )

	def handler(self):
		"""Receives a message and returns it."""
		buffer = ''
		while 1:
			x = self.sock.recv(1)
			if x != '\n':
				buffer = buffer.__add__(x)
			else:
				#I've got a complete message... :-)
				self.raw_handler(buffer)
				return buffer
			
	def raw_handler(self, msg):
		"""The raw_handler just manages the PING/PONG...but also if debug==1 it outputs every message.
		It dos not do something else and should not be used for something else...
		"""
		if debug == 1:
			print 'INPUT==>%s' %(msg, )
		if msg[0:6] == 'PING :':
			ping_key = msg[6:]
			if show_ping_pong == 1:
				print 'PING/PONG %s' %(ping_key, )
			self.send('PONG :%s' %(ping_key, ))
			
	def handle_forever(self):
		"""Calls the handler() ... forever ;-)"""
		while 1:
			message = self.handler()
			#Give it to someone...
			self.handle_command(message)

	def handle_command(self,msg):
		"""This function is called but doesn't do anything.
		It should be replaced by another when you subclass the IRC class
		"""
		#Do nothing, this must be rewritten in the subclass :-)
		print '-.-'

class SimpleIRCClient(IRC):
	def __init__(self, conn_data, nick):
		IRC.__init__(self, conn_data, nick)
		self.send('JOIN #_JD_')
		print 'START handle_forever()!!!'
		self.handle_forever()
	def handle_commmand(self, msg):
		"""Handles all the commands in a more sophisticated way than IRC.handle_command.msg.."""
		print 'HALLLLOOOOOO!!!!!!'
		#Zerleg das ganze Zeugs...
		#Zuerst mal bis zum ':'
		msg_list = msg.split(':')
		command_part = msg_list[1]
		text_part    = msg_list[2]
		
		#Zerschnipsele den Command part...
		commandos = command_part.split(' ')
		sender = commandos[0]
		command = commandos[1]
		rest = commandos[2:]
		
		#Privmsg?
		if command == 'PRIVMSG':
			sender_nick_ = sender.split('!')
			sender_nick = sender_nick_[0]
			print '%s has sent you: %s' %(sender_nick, text_part)

	
irc = SimpleIRCClient(("irc.euirc.net", 6667), 'hu9')
Danke für Hilfe im voraus... (und nein, ich will keine fertige IRC-Bibliothek verwenden und ja...der Code is wahrscheinlich nicht schön)...

Edit (Leonidas): Code in Python-Tags gesetzt.
Zuletzt geändert von Nicht_zu_definieren am Freitag 21. April 2006, 17:46, insgesamt 3-mal geändert.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Freitag 21. April 2006, 17:42

...erzeugt bei mir folgende Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "test.py", line 31, in ?
    irc = SimpleIRCClient(("server", 6667), 'nickname')
  File "test.py", line 23, in __init__
    IRC.__init__(self, conn_data, nick)
AttributeError: class IRC has no attribute '__init__'
Und in der letzten Zeile steht es ja: Du versuchst in Zeile 23 die nicht existierende Funktion IRC.__init__ aufzurufen.

Naechstes Mal Fehlermeldung mitposten, oder besser: Fehlermeldung vorher lesen...

Uebrigens benutzt du den Begriff "Objekt" falsch. Du meinst wohl "Funktionen" oder "Attribute". Ein Objekt ist die Instanz einer Klasse.
Nicht_zu_definieren
User
Beiträge: 21
Registriert: Freitag 21. April 2006, 17:01
Kontaktdaten:

Freitag 21. April 2006, 17:49

So :D jetzt habs ich geschafft^^

Danke Leonidas, hab nicht gewusst wei man das macht, dass er es als Python Code anzeigt...

An Rebecca: Ja, ok...ich will das Attribut neu definieren ;)
Hab das jetzt oben editiert, so dass der komplette Code da ist...

Ich hoffe, ihr könnt ihn halbwegs lesen, und ich hoffe, dass er nicht allzu schlecht ist.
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Freitag 21. April 2006, 18:18

Hi

Mach einfach das class IRC: am Anfang der Datei weg. Dann soltle es gehen.

Gruss
Nicht_zu_definieren
User
Beiträge: 21
Registriert: Freitag 21. April 2006, 17:01
Kontaktdaten:

Freitag 21. April 2006, 20:31

Danke :D

Leonidas hat mir geraten mal asyncore und asynchat anzuschauen...was ich auch gemacht habe...
Allerdigs stoße ich da auch auf Probleme...
Basierend auf dem Code von Sorgenkind in http://www.python-forum.de/topic-1903.html habe ich folgenden Code geschrieben:

Code: Alles auswählen

import asyncore
import asynchat
import socket

class IRCBot(asynchat.async_chat):
    def __init__(self,server,nick,port=6667):
        asynchat.async_chat.__init__(self)
        self.set_terminator("\r\n")
        self.create_socket(socket.AF_INET,socket.SOCK_STREAM)
        self.connect((server,port))
        self.send('NICK :%s' %(nick, ))
        self.send('USER %s %s %s :%s' %(nick, server, nick, 'test'))

    def found_terminator(self):
		self.handle_message(self.message)
		self.message = ''

    def collect_incoming_data(self,data):
        self.message = self.message + data
        
	def handle_message(self, msg):
		print msg

bot = IRCBot("irc.quakenet.org", "test")

try:
	asyncore.loop()
except KeyBoardInterrupt:
	print 'Byebye...'
Ich bekomme allerdings folgende (für mich kryptische) Fehlermeldung:
warning: unhandled connect event
error: uncaptured python exception, closing channel <__main__.IRCBot connected a
t 0x9bdd28> (exceptions.AttributeError:'_socketobject' object has no attribute '
message' [C:\PYTHON24\lib\asyncore.py|read|69] [C:\PYTHON24\lib\asyncore.py|hand
le_read_event|391] [C:\PYTHON24\lib\asynchat.py|handle_read|134] [asynbot.py|col
lect_incoming_data|29] [C:\PYTHON24\lib\asyncore.py|__getattr__|366])

Die Fehlermeldung bekomme ich gleich, also es ist (ziemlcih sicher) nicht der Server der die Verbindung schließt...
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Freitag 21. April 2006, 21:52

Hi

Mal meine Änderungen:
1. Mach im __init__ kein self.send weil der socket noch nicht verbunden ist, mach das bei handle_connect und später um weitere Daten zu schicken erst bei handle_write. handle_write wird aufgerufen wenn der Socket bereit ist um weitere Daten zu schicken.

Bei send_command wird der command zwischengespeichert und erst wenn der Socket bereit (handle_write) ist werden soviele Daten geschick wie möglich, darum auch die verwendung von sent

2. Bei found_terminator ist self.message noch undefiniert, weil collect_incoming_data nicht aufgerufen wurde, mach bei __init__ noch self.message = ''

3. Damit asyn_core auch anständige Fehlermeldungen ausgibt nocht die Funktion handle_error implementieren.

Hier noch der Code dazu:

Code: Alles auswählen

import asyncore
import asynchat
import socket

class IRCBot(asynchat.async_chat):
    def __init__(self,server,nick,port=6667):
        asynchat.async_chat.__init__(self)
        self.set_terminator("\r\n")
        self.create_socket(socket.AF_INET,socket.SOCK_STREAM)
        self.connect((server,port))
        self.nick = nick
        self.server = server
        self.message = '' #input buffer
        self.buffer = ''  # output buffer

    def found_terminator(self):
        self.handle_message(self.message)
        self.message = ''

    def collect_incoming_data(self,data):
        self.message = self.message + data

    def handle_connect(self):
        self.send('NICK :%s' %(self.nick, ))
        self.send('USER %s %s %s :%s' %(self.nick, self.server, self.nick, 'test'))

    def handle_message(self, msg):
        print msg

    def send_command(self, cmd):
        self.buffer += cmd+'\r\n'

    def handle_write(self):
        sent = self.send(self.buffer)
        self.buffer = self.buffer[sent:]

    def handle_error(self):
        import traceback
        traceback.print_exc()


bot = IRCBot("irc.quakenet.org", "test")
try:
    asyncore.loop()
except KeyBoardInterrupt:
    print 'Byebye...'
Gruss
Antworten