Törmäsin vallan mielenkiintoiseen ongelmaan tehdessäni jälleen kerran uutta IRC-systeemiä pythonilla. jouduin päivittämään PYTHONversioksi kolmosen, koska eräs grafiikkakirjasto noin vaati, ja törmäsin koodissani:
# -*- coding:cp1252 -*-
import socket
sok = socket.socket()
serveri = "irc.quakenet.org"
portti = "6667"
nick = "HerraP"
kayttajanimi = "HerraP"
oikeanimi = "HerraP"
kanavat = ['#kanava1', '#kanava2']
def paa(serveri, portti, nick, kayttajanimi, oikeanimi, kanavat, sok):
sok.connect((serveri, int(portti)))
sok.send('USER ' + str(kayttajanimi) + ' ' + str(nick) + ' ' + str(serveri) + ' :' + str(oikeanimi) + '\r\n').encode('utf8')
#sok.send('USER ' + kayttajanimi + ' ' + nick + ' ' + serveri + ' :' + oikeanimi + '\r\n')
sok.send('NICK ' + nick + '\r\n')
for kanava in kanavat:
sok.send('JOIN ' + kanava + '\r\n')
while 1:
teksti = sok.recv(4096)
print(teksti)
if teksti[0:4] == 'PING':
sok.send('PONG ' + teksti.split() [ 1 ] + '\r\n')
paa(serveri, portti, nick, kayttajanimi, oikeanimi, kanavat, sok)ongelmaan
Traceback (most recent call last): File "C:\Documents and Settings\Lotto\Työpöytä\seta.py", line 22, in <module> File "C:\Documents and Settings\Lotto\Työpöytä\seta.py", line 12, in paa TypeError: must be bytes or buffer, not str >>>
Mistähän kummasta tämä version 2.6 ja 3.1.1 versioiden ero mahtaa johtua?
Python 3:ssa tekstit ovat lähtökohtaisesti Unicode-tekstejä, ja jos haluat niistä tavuja (kuten tuossa tapauksessa), ne täytyy enkoodata jotenkin. Vilkaise Python-oppaan merkistöliitettä, asia luultavasti pätee suurelta osin myös Python 3:een, kunhan muistat tämän viestin ensimmäisen lauseen. Jos olet kärsimätön, oppaan lopussa on suoraan tarkoitukseesi soveltuva esimerkki.
Lotto kirjoitti:
mysliversioksi
Miten se mysli tähän juttuun liittyy?
Okei, tämä:
# -*- coding:ascii-*-
import socket
sok = socket.socket()
serveri = str("irc.quakenet.org")
portti = "6667"
nick = str("seta")
kayttajanimi = str("setamies")
oikeanimi = str("setamies")
kanavat = ['#pena', '#vapaadyykkarit']
def paa(serveri, portti, nick, kayttajanimi, oikeanimi, kanavat, sok):
sok.connect((serveri.encode('UTF-8'), int(portti)))
sok.send('USER ' + kayttajanimi.encode('UTF-8') + ' ' + nick.encode('UTF-8') + ' ' + serveri.encode('UTF-8') + ' :' + oikeanimi.encode('UTF-8') + '\r\n')
sok.send('NICK ' + nick + '\r\n')
for kanava in kanavat:
sok.send('JOIN ' + kanava + '\r\n')
while 1:
teksti = sok.recv(4096)
print(teksti)
if teksti[0:4] == 'PING':
sok.send('PONG ' + teksti.split() [ 1 ] + '\r\n')
paa(serveri, portti, nick, kayttajanimi, oikeanimi, kanavat, sok)muutti tilannetta näion:
Traceback (most recent call last): File "C:\Documents and Settings\Lotto\Työpöytä\seta.py", line 21, in <module> File "C:\Documents and Settings\Lotto\Työpöytä\seta.py", line 12, in paa TypeError: Can't convert 'bytes' object to str implicitly
Ja tuosta myslijutusta, taisin olla ajatuksissa ku just ennen viestiä kasannu myslikantaa :D
Edelleenkin ne tekstit ovat oletuksena Unicode-tekstejä ja ne pitää enkoodata. Kannattaisi varmaan ensin muodostaa koko teksti ja vasta sitten enkoodata kaikki kerralla, siis sok.send((a+b+c).encode('UTF-8')). Vastaavasti recv-funktion perään kuuluisi decode, mutta toki ensin täytyy tunnistaa lähettäjän merkistö. IRC-protokolla sinänsä on ASCII-pohjainen, joten erikoismerkit esiintyvät vain muussa datassa kuten viesteissä.
Aihe on jo aika vanha, joten et voi enää vastata siihen.