Гость
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / [python] - тонкие отличия os.popen2 и subprocess.Popen / 11 сообщений из 11, страница 1 из 1
21.03.2017, 14:36
    #39424113
Vladimir Baskakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[python] - тонкие отличия os.popen2 и subprocess.Popen
Код: python
1.
2.
3.
4.
5.
6.
#1
p=Popen(cmd, bufsize=-1, stdin=PIPE, stdout=PIPE)
self.to_=p.stdin
self.from_=p.stdout
#2        
self.to_, self.from_ = os.popen2(cmd)



коллеги, помогите начинающему питонисту. (использую Python 2.7, windows)
- есть 2 альтернативных способа запуска дочернего процесса.
второй работает хорошо, стабильно, приложения получают ввод и отдают вывод, в первом же варианте одно из приложений работает некорректно. а второе нормально.

Я захотел разобраться почему так, но открыв os.py так и не нашел, где оно для винды затягивает функцию popen2 - нашел только фрагмент для юникса
Код: python
1.
2.
3.
4.
5.
# Supply popen2 etc. (for Unix)
if _exists("fork"):
    if not _exists("popen2"):
        def popen2(cmd, mode="t", bufsize=-1):
            """Execute the shell command 'cmd' in a sub-process.  On UNIX, 'cmd'"""


и тут стало вообще интересно как это устроено.... если кто подскажет - большое спасибо.

В принципе, работающего варианта пока хватает, но под третьим python-ом оно уже работать перестанет, а было бы неплохо и там тоже.
...
Рейтинг: 0 / 0
21.03.2017, 19:19
    #39424359
FishHook
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[python] - тонкие отличия os.popen2 и subprocess.Popen
Vladimir Baskakov,

os.popen и остальные его братья - устаревшие методы, его никто их не поддерживает и они крайне не рекомендуются к использованию. Просто забудьте про них и все.
...
Рейтинг: 0 / 0
22.03.2017, 05:44
    #39424510
Vladimir Baskakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[python] - тонкие отличия os.popen2 и subprocess.Popen
Спасибо .

Но код работает именно с ним. Устаревшим. А с новым глючит. Именно поэтому я и задал вопрос - я хочу заменить на новое, но чтобы работало, а не глючило (((
...
Рейтинг: 0 / 0
22.03.2017, 07:10
    #39424517
FishHook
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[python] - тонкие отличия os.popen2 и subprocess.Popen
Vladimir BaskakovА с новым глючит.
Что значит "глючит"?
Дайте минимальный воспроизводимый пример некорректного поведения.
...
Рейтинг: 0 / 0
22.03.2017, 09:54
    #39424586
Vladimir Baskakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[python] - тонкие отличия os.popen2 и subprocess.Popen
минимального нет.

Есть скрипт
https://github.com/zztrilobit/go_assistant/blob/master/goban.py

предназначение которого - рисовать визуальный интерфейс к играющим в го утилитам комакндной строки. рисовать с нужными мне особенностями - так то есть готовые решения, но мне занадобилось поменять

class GoEngine:
def StartEngin(self,cmd):

- запускает таковую утилиту
def gtp(self, command):
- посылает ей команду и считывает ответ.

Сейчас отладка проходит с двумя движками - GNUGO и leela.

GNUGO независимо от библиотечной функции которая запустила и подключилась к каналам дает правильный ответ.

leela пока нормально коммуницирует только при запуске с помощью os.popen2 а - при запуске через p=Popen(cmd, bufsize=-1, stdin=PIPE, stdout=PIPE)
self.to_=p.stdin
self.from_=p.stdout


в ответ на любую команду дает неправильный ответ который вылавливается тут:
assert(self.from_gnugo.read(1) == "\n") - вот мне любопытно, почему так. Откуда в потоке взялся "\n"

Чтобы воспроизвести, естественно нужно скачивать эту самую леелу, что конечно всем будет лень.... поэтому я задал вопрос более общий :

- где посмотреть исходник устаревшей и новой функции (класса) чтобы найти отличия в работе.
...
Рейтинг: 0 / 0
22.03.2017, 10:27
    #39424611
Vladimir Baskakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[python] - тонкие отличия os.popen2 и subprocess.Popen
FishHook,

Код: python
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
from sys import exit as sysexit
from os.path import splitext
import os
from subprocess import *
import time
import popen2

# интерактив с энжином
class GoEngine:
    def __init__(self):
        self._gtpnr = 1
        self.running=False
    
    def StartEngin1(self,cmd):
        print "starting ", cmd
        self.to_gnugo,self.from_gnugo = os.popen2(cmd)
        self.running=True

    def StartEngin2(self,cmd):
        print "starting ", cmd
        p=Popen(cmd, bufsize=-1, stdin=PIPE, stdout=PIPE)
        #p=Popen(["leela080.exe","--gtp"], shell=True, bufsize=-1, stdin=PIPE, stdout=PIPE)
        self.to_gnugo=p.stdin
        self.from_gnugo=p.stdout
        self.running=True
    
    def gtp(self, command):
        if not self.running : 
            # raise BasicError("OOOOPS..... NO GTP ENGINE!!!!")
            print ("OOOOPS..... NO GTP ENGINE!!!!")
            return
        verbose = True
        cmd = str(self._gtpnr) + " " + command
        if verbose:
            print cmd
            sys.stdout.flush()
        self.to_gnugo.write(cmd + "\n")
        self.to_gnugo.flush()
        status = self.from_gnugo.read(1)
        value = status
        while not status == "\n":
            status = self.from_gnugo.read(1)
            value += status
        assert(self.from_gnugo.read(1) == "\n")
        if verbose:
            print value
        retval=value[1 + len(str(self._gtpnr)):]
        #todo - тут надо бы вылавливать ошибки хотя бы так
        self.is_ok=value[0]=="="
        if not self.is_ok:
            print "gtp error!!! "+retval
        self._gtpnr += 1
        return retval
            
    def time_by_move(self, seconds) :
        # всю партию машина играет в режиме байоми, по нужному числу секунд на ход
        return self.gtp("time_settings 1 "+str(seconds)+" 1")

    def quit(self):
        r=self.gtp('quit')
        self.running=False
        return r
        
    def undo(self):
        return self.gtp('undo')

e=GoEngine()
e.StartEngin1("leela080.exe --g")
e.time_by_move(3)
e.quit()
e.StartEngin2("leela080.exe --g")
e.time_by_move(3)
e.quit()


..\python.exe test.py 1>1 2>2


Результаты
stdout (1) :
starting leela080.exe --g
1 time_settings 1 3 1
=1

2 quit
=2

starting leela080.exe --g
3 time_settings 1 3 1


stderr (2) :
110 feature weights loaded, 2608 patterns
BLAS core: MKL Intel(R) Streaming SIMD Extensions 4.2 (Intel(R) SSE4.2) enabled processors
Traceback (most recent call last):
File "test.py", line 77, in <module>
e.time_by_move(3)
File "test.py", line 62, in time_by_move
return self.gtp("time_settings 1 "+str(seconds)+" 1")
File "test.py", line 49, in gtp
assert(self.from_gnugo.read(1) == "\n")
AssertionError


коммент - в stderr попал как вывод leela
110 feature weights loaded, 2608 patterns
BLAS core: MKL Intel(R) Streaming SIMD Extensions 4.2 (Intel(R) SSE4.2) enabled processors
Traceback (most recent call last):

так и сообщение об ошибке на assert.

ну и понятно что второй процесс энжина остался висеть в памяти и жрать процессорное время
...
Рейтинг: 0 / 0
22.03.2017, 17:10
    #39425101
Vladimir Baskakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[python] - тонкие отличия os.popen2 и subprocess.Popen
..... в общем наверное придется делать типа такого....
http://eyalarubas.com/python-subproc-nonblock.html

похоже по простому не выйдет ..... ну или оставить все как есть, на неправильной библиотечке... ((((((((
...
Рейтинг: 0 / 0
23.03.2017, 22:50
    #39426128
maxkar
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[python] - тонкие отличия os.popen2 и subprocess.Popen
Vladimir Baskakovпохоже по простому не выйдет

Ну я не знаю, зачем вы на неблокирующий ввод/вывод смотрите (он вашу проблему не решит все равно).

Вам по идее банальное
Код: python
1.
p=Popen(cmd, bufsize=-1, stdin=PIPE, stdout=PIPE, universal_newlines=True)


нужно.
...
Рейтинг: 0 / 0
24.03.2017, 07:31
    #39426228
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[python] - тонкие отличия os.popen2 и subprocess.Popen
maxkar,

есть еще пакет multiprocessing.
...
Рейтинг: 0 / 0
24.03.2017, 09:36
    #39426283
Vladimir Baskakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[python] - тонкие отличия os.popen2 и subprocess.Popen
....... решено. os.popen2 открывал каналы, убирающие \r из потока. В отличие от subprocess.popen. искать, почему так, уже лень.

просто доработал цикл чтения ........
...
Рейтинг: 0 / 0
24.03.2017, 09:39
    #39426287
Vladimir Baskakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[python] - тонкие отличия os.popen2 и subprocess.Popen
maxkar ,

universal_newlines=True

- да. наверное это оно. теперь буду знать, спасибо
...
Рейтинг: 0 / 0
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / [python] - тонкие отличия os.popen2 и subprocess.Popen / 11 сообщений из 11, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]