LINUX.ORG.RU

[python] юникот и байтосроки во 2 и 3 версиях

 


0

1

Допустим я хочу чтобы запуская скрипт во 2м и 3м петонах, я был уверен юникодные или байтовые строки там.

вот немного г-внокода:

lol.py

# -*- coding: utf-8 -*-

#from __future__ import absolute_import, division, print_function, unicode_literals
import sys

if sys.version_info < (3, 0):
    strtypes = {'bstr': str, 'ustr': unicode}
else:
    strtypes = {'bstr': bytes, 'ustr': str}

def isbstr(s):
    return type(s) is strtypes['bstr']

def isustr(s):
    return type(s) is strtypes['ustr']

def ustr(s):
    if isustr(s):
        return s
    elif isbstr(s):
        return s.decode('utf-8')
    else:
        return strtypes['ustr'](s)

def bstr(s):
    if isbstr(s):
        return s
    elif isustr(s):
        return s.encode('utf-8')
    else:
        return strtypes['ustr'](s).encode('utf-8')

if __name__ == '__main__':
    pass

и типа скрипт, активно жонглирующий строками: ololo.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

#from __future__ import absolute_import, division, print_function, unicode_literals
from pprint import pprint
import sys
from lol import *

class Smth:
    a = 13
    b = 666
    def __repr__(self):
        return '((%d/%d))' % (self.a, self.b)
    def __str__(self):
        return '[[%d/%d]]' % (self.a, self.b)
    #def __unicode__(self):
    #    return '{{%d/%d}}' % (self.a, self.b)

if __name__ == '__main__':
    print(sys.version_info)
    s = b'\xd0\xbb\xd0\xbe\xd0\xbb\xd0\xb4'
    s1 = ustr(s)
    s2 = bstr(s)
    pprint(s1)
    pprint(s2)
    print('')
    smth = Smth()
    #pprint(smth)        
    #pprint(repr(smth))  
    #pprint(str(smth))   
    #try:                
    #    pprint(unicode(smth)):
    #except:
    #    pass
    pprint(bstr(smth))  
    pprint(ustr(smth))  
    print('')

Нормальное решение или может какие косяки? 2to3 калечить такую конструкцию не будет?

Кстати, можешь глянуть на six, там много чего полезного для сохранения совместимости.

baverman ★★★
()

чисто придирка

вот так делать не надо:

from lol import *

подключай либо поимённо-поштучно, либо так:

import lol
shty ★★★★★
()
Ответ на: комментарий от dismal_faun

странную тут хреноту обнаружил

# -*- coding: utf-8 -*-

class Smth:
    pass
    #def __repr__(self):
    #    return 'smth repr'
    #def __str__(self):
    #    return 'smth str'
    #def __unicode__(self):
    #    return 'smth unicode'

if __name__ == '__main__':
    smth = Smth()
    print(smth)
    print(repr(smth))
    print(str(smth))
    print(unicode(smth))
в виртуальном окружении сегфолтится при вызове unicode у объектов
(env27) % python smth.py
<__main__.Smth instance at 0x7f60729abcf8>
<__main__.Smth instance at 0x7f60729abcf8>
<__main__.Smth instance at 0x7f60729abcf8>
zsh: segmentation fault  python smth.py
никто с таким не сталкивался?

dismal_faun ★★
() автор топика
Ответ на: комментарий от dismal_faun

мда...

(gdb) run smth.py
Starting program: /mnt/stuff/env27/bin/python smth.py
[Thread debugging using libthread_db enabled]
<__main__.Smth instance at 0x7ffff7f21cf8>
<__main__.Smth instance at 0x7ffff7f21cf8>
<__main__.Smth instance at 0x7ffff7f21cf8>

Program received signal SIGSEGV, Segmentation fault.
0x0000003c5708594e in PyObject_GetAttr () from /usr/lib64/libpython2.7.so.1.0
(gdb) bt
#0  0x0000003c5708594e in PyObject_GetAttr () from /usr/lib64/libpython2.7.so.1.0
#1  0x0000003c57085e64 in PyObject_Unicode () from /usr/lib64/libpython2.7.so.1.0
#2  0x0000003c570b48e2 in ?? () from /usr/lib64/libpython2.7.so.1.0
#3  0x0000003c5709e703 in ?? () from /usr/lib64/libpython2.7.so.1.0
#4  0x0000003c5704b202 in PyObject_Call () from /usr/lib64/libpython2.7.so.1.0
#5  0x0000003c570e01af in PyEval_EvalFrameEx () from /usr/lib64/libpython2.7.so.1.0
#6  0x0000003c570e2469 in PyEval_EvalCodeEx () from /usr/lib64/libpython2.7.so.1.0
#7  0x0000003c570e2582 in PyEval_EvalCode () from /usr/lib64/libpython2.7.so.1.0
#8  0x0000003c570fbf6c in ?? () from /usr/lib64/libpython2.7.so.1.0
#9  0x0000003c570fcd40 in PyRun_FileExFlags () from /usr/lib64/libpython2.7.so.1.0
#10 0x0000003c570fd8ff in PyRun_SimpleFileExFlags () from /usr/lib64/libpython2.7.so.1.0
#11 0x0000003c5710e730 in Py_Main () from /usr/lib64/libpython2.7.so.1.0
#12 0x0000003c5541eebd in __libc_start_main () from /lib64/libc.so.6
#13 0x00000000004008a9 in _start ()

dismal_faun ★★
() автор топика

имхо костылизм страшный, я от такого подхода отказался. Я бы двигался в сторону 2to3... Правда, тут удобство в том что не надо ничего конвертировать.

PS у меня не сегфотится, но я virtenv не использую.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

да, 2to3 надо будет покурить поподробнее;

вне виртуалэнв у меня оно тоже не сегфолтится

dismal_faun ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.