Подтвердить что ты не робот

Как обнаружить изнутри Python, управляются ли пакеты с помощью conda

Я хотел бы обнаружить в общем виде изнутри сеанса Python, управляется ли он кондой.

Несколько идей, которые недостаточно для того, чтобы быть полезными:

1: Использовать переменные среды

Как указано в Как найти имя среды conda, в которой работает мой код?

import os
is_conda = 'CONDA_PREFIX' in os.system or 'CONDA_DEFAULT_ENV' in os.system

Это, похоже, не работает в среде root conda, где эти переменные не всегда определены. Он также имеет потенциальные ложные срабатывания, если conda активируется, когда вы используете другую установку Python.

2: проверьте исполняемый путь

import sys
is_conda = ('anaconda' in sys.executable) or ('miniconda' in sys.executable)

Это будет работать в случае, если пользователи установят anaconda/miniconda в путь по умолчанию. В противном случае это может закончиться. Также легко представить ложные срабатывания.

3. Проверьте информацию о версии

Как указано в ответах на чтобы определить, является ли пользовательская среда python анакондой, вы можете проверить строку версии Python в некоторых случаях:

import sys
is_conda = ('Continuum Analytics' in sys.version) or ('Anaconda' in sys.version)

В настоящее время это работает для Python, установленного по каналу по умолчанию, но это довольно хрупкое и может сломаться в будущем, особенно с изменением названия компании Continuum. Это также, вероятно, не удается, если Python установлен из стороннего источника, такого как conda-forge.

4. Проверьте conda импорт

try:
    import conda
except:
    is_conda = False
else:
    is_conda = True

Это работает до тех пор, пока вы находитесь в корневой среде conda, но обычно терпите неудачу, если вы находитесь в другой conda env, где пакет conda не установлен по умолчанию.

5: Попробуйте conda посмотреть, работает ли он

Предложение от Atto Allas ниже:

import subprocess
try:
    retcode = subprocess.call(['conda', 'install', '-y', 'pip'])
except:
    is_conda = False
else:
    is_conda = (retcode == 0)

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


Есть ли вообще общий способ обнаружения с Python, управляется ли эта установка Python кондой?

4b9b3361

Ответ 1

import sys, os
is_conda = os.path.exists(os.path.join(sys.prefix, 'conda-meta'))

Ответ 2

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

def is_conda():
    import sysconfig
    return 'conda-bld' in sysconfig.get_config_var("abs_srcdir")

Я не уверен в этом конкретном ключе "abs_srcdir", но sysconfig.get_config_values() имеет много элементов, которые могут работать. С моим системным python это:

>>> sysconfig.get_config_var("abs_srcdir")
'/Library/Caches/com.apple.xbs/Binaries/python/python-97.50.7~5/TempContent/Objects/2.7/python'

И с моим conda python это:

In [17]: sysconfig.get_config_var("abs_srcdir")
Out[17]: '/Users/ilan/minonda/conda-bld/python-3.6_1482520641897/work/Python-3.6.0'

Я надеюсь, что флаги времени компиляции более надежны, чем проверки времени выполнения. Такие вещи, как "is conda in sys.prefix", могут быть смущены установкой Python.org в подкаталоге "conda". Но флаги времени компиляции должны быть в порядке.

Ответ 3

Может быть, это?

from subprocess import check_output, CalledProcessError
import sys


def is_conda_managed():
    try:
        out = check_output(['conda', 'env', 'list']).decode('utf-8')
        lines = (line for line in out.splitlines() if line[:1] != '#')
        roots = set(line.split()[-1] for line in lines if line.strip())
    except CalledProcessError:
        roots = set()

    return sys.prefix in roots

Ответ 4

Я думаю, что лучший подход - это вариант Ответ Росс Хинтена: в процессе сборки conda создает файл под названием {sys.prefix}/conda-meta/history, поэтому проверка его присутствия должна сообщить вам, используете ли вы conda в разумной степени:

import sys, os
is_conda = os.path.exists(os.path.join(sys.prefix, 'conda-meta', 'history'))

По-прежнему возможно иметь ложные срабатывания с этим подходом, но мне кажется очень маловероятным, если не сделать намеренно.

Ответ 5

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

└─╼ which -a python
/Users/me/anaconda/bin/python
/usr/bin/python
┌─[ ~/myPython]
└─╼ /Users/me/anaconda/bin/python
Python 2.7.13 |Anaconda 2.2.0 (x86_64)| (default, Dec 20 2016, 23:05:08) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
Anaconda is brought to you by Continuum Analytics.
Please check out: http://continuum.io/thanks and https://anaconda.org
>>> quit()
┌─[ ~/myPython]
└─╼ /usr/bin/python
Python 2.7.10 (default, Feb  7 2017, 00:08:15) 
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> quit()
┌─[ ~/myPython]
└─╼ source activate py36
(py36) ┌─[ ~/myPython]
└─╼ which -a python
/Users/me/anaconda/envs/py36/bin/python
/Users/me/anaconda/bin/python
/usr/bin/python
└─╼ python
Python 3.6.2 |Continuum Analytics, Inc.| (default, Jul 20 2017, 13:14:59) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> quit()
(py36) ┌─[ ~/myPython]
└─╼ which -a python
/Users/me/anaconda/envs/py36/bin/python
/Users/me/anaconda/bin/python
/usr/bin/python

- строки:   Python 2.7.10 (по умолчанию   Python 2.7.13 | Anaconda 2.2.0 (x86_64)   Python 3.6.2 | Continuum Analytics, Inc.

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

In [46]: platform.python_build()
Out[46]: ('default', 'Jul 20 2017 13:14:59')

In [47]: platform.python_compiler()
Out[47]: 'GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)'

In [48]: platform.python_implementation()
Out[48]: 'CPython'

это альтернативы conda, я ожидаю, поэтому q будет казаться шире, чем conda.

(это ответ, только потому, что это мой первый пост SO, и у меня только одна репутация)