powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / [python] - тонкие отличия os.popen2 и subprocess.Popen
11 сообщений из 11, страница 1 из 1
[python] - тонкие отличия os.popen2 и subprocess.Popen
    #39424113
Vladimir Baskakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: 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
[python] - тонкие отличия os.popen2 и subprocess.Popen
    #39424359
Фотография FishHook
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vladimir Baskakov,

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

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

Есть скрипт
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
[python] - тонкие отличия os.popen2 и subprocess.Popen
    #39424611
Vladimir Baskakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
[python] - тонкие отличия os.popen2 и subprocess.Popen
    #39425101
Vladimir Baskakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
..... в общем наверное придется делать типа такого....
http://eyalarubas.com/python-subproc-nonblock.html

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

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

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


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

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

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

universal_newlines=True

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


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