Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Python 2.6 sekä 3.0 ja soketit

Lotto [25.01.2010 15:51:09]

#

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?

Metabolix [25.01.2010 16:14:06]

#

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?

Lotto [25.01.2010 22:55:30]

#

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

Metabolix [25.01.2010 23:24:55]

#

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ä.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta