Перечислите область видимости переменной с вложенными ifs в Python 3 - PullRequest
0 голосов
/ 13 октября 2018

На основании этого ответа и того факта, что списочные представления больше не «пропускают» свою переменную в Python 3.x, как я могу реализовать / переписать это выражение в Python 3?

>>> import sys
>>> sys.version[:5]
'3.6.5'
>>> import psutil
>>> psutil.__version__
'5.4.7'
>>> [port.laddr.port for proc in psutil.process_iter(attrs=['name']) if 'sshd' in proc.info['name'] if any([port.status == psutil.CONN_LISTEN for port in proc.connections()])]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <listcomp>
NameError: name 'port' is not defined

Ответы [ 2 ]

0 голосов
/ 13 октября 2018

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

Я разделил его на два понимания, чтобы они соответствовали моиммозг.

procs = [proc for proc in psutil.process_iter(attrs=['name'])
         if 'sshd' in proc.info['name']]
ports = [port.latter.port for proc in procs
         for port in proc.connections() if port.status==psutil.CONN_LISTEN]

print(ports)
0 голосов
/ 13 октября 2018

Во-первых, это понимание списка довольно стилистично.Совершенно непостижимо для любого, кто пытается это прочитать.Отступы - ваш друг, а количество строк кода не является премией.Изменение отступа, чтобы сделать его более читабельным:

ports = [
    port.laddr.port
    for proc in psutil.process_iter(attrs=['name'])
    if 'sshd' in proc.info['name']
    if any([port.status == psutil.CONN_LISTEN for port in proc.connections()])
]

Теперь проблема становится понятной.Постижения списков не пропускают свою область действия в Python 3. За пределами понимания списка ports (если оно не сработало из-за NameError), не было бы объекта с именем proc.

Тем не менее, вы действительно получаете ошибку имени, потому что понимание списка внутри вашего вызова к any также не пропускает его сферу.Никакая переменная port не выходит за пределы понимания родительского списка, и вы получаете NameError.

Во-вторых, чтобы ответить на ваш вопрос, вам, вероятно, следует вообще избегать понимания списка.Вы пытаетесь сделать слишком много в одном утверждении.Создайте список ports.Выполните итерацию ваших процессов в цикле for и append в соответствии с требуемой логикой.

Чтобы продемонстрировать:

ports = []
def validate_proc(proc):
    return any(
        port.status == psutil.CONN_LISTEN
        for port in proc.connections()
    )
for proc in in psutil.process_iter(attrs=['name']):
    if not 'sshd' in proc.info['name']:
        continue
    if not validate_proc(proc):
        continue
    for port in proc.connections():
        ports.append(port.laddr.port)

Здесь я предположил, что вы хотели все портов для данного процесса, если любой портов соответствует вашему заданному критерию, и в противном случае вам не нужен ни один из них.Вот как я читаю ваше понимание.Если это не то, что вы ищете, тогда я могу это изменить.(Это конкретный пример того, почему следует избегать использования больших списков.)

...