Python36 \ Scripts запускается на неправильной версии Python - PullRequest
0 голосов
/ 05 июля 2019

поэтому я создал пакет, содержащий один файл python, который во время установки отправляется в Python36 \ Scripts.Но на WinOS у меня есть 3 глобальных интерпретатора Python.

Main - это python2.7, второй - python3.6, а третий - python3.7.

Пакет 'my_package' установлен в python3.6 в C: \ Python36 \ Lib \ site-packages \ my_package и содержит файл python settings.py

Скрипт 'my_script.py'также устанавливается в python3.6 в C: \ Python36 \ Scripts \ my_script.py

Так что теперь, когда вы знаете, в чем заключается проблема, когда я пишу в cmd my_script.py, он будет запускаться через python2.7 будет сгенерировано исключение, потому что оно не является дружественным для python2.7.

В UNIX это будет легко решено с помощью строки shebang.Как вызвать my_script.py с интерпретатором python3.6.

Прежде чем ответить, я попробовал:

  • cmd находится в режиме администратора

  • py -3.6 my_script.py запуск приведет к [Errno 2] Нет такого файла или каталога

структура пакета:

  1. my_package
  2. my_package
    • __ init_.py
    • settings.py
  3. сценариев
    • __ init_.py
    • my_script.py
  4. setup.py

setup.py

from setuptools import setup

with open("README.md", "r") as fh:
    long_description = fh.read()

setup(name='my_package',
      version='0.1.4',
      description='Work in progress',
      long_description=long_description,
      long_description_content_type="text/markdown",
      author=',
      author_email='',
      packages=['my_package'],
      zip_safe=False,
      install_requires=['SQLAlchemy', 'pandas'],
      scripts=['scripts/my_script.py']
      )

my_script.py

from distutils.sysconfig import get_python_lib
sys.stdout.write(get_python_lib())
sys.path.insert(0, get_python_lib())

from my_package.settings import *

Ответы [ 2 ]

1 голос
/ 06 июля 2019

при вызове python script.py файл script.py находится в операционной системе , поэтому вы должны указать полный путь к script.py, т.е. python c:\python36\scripts\script.py.

Если вы хотите, чтобы python нашел скрипт, вы должны вызвать python -m script (без .py), который запустит python и ищет в sys.path модуль с именем script. Вы можете просто позвонить script.py без предшествующего python, но это сложнее:

  • Правильный интерпретатор Python должен быть зарегистрирован в Windows как исполняемый файл для использования при открытии файлов *.py, и одновременно может быть зарегистрирован только один интерпретатор
  • Каталог c:\python36\scripts должен быть на вашем пути

Windows не использует #! shebang «протокол», в который вы помещаете команду для выполнения файла в первую строку файла

0 голосов
/ 07 июля 2019

Я сделал обходной путь для этой проблемы, который будет хорошо работать. Вместо одного скрипта теперь у меня есть my_script.py и my_scriptV3.py ... и теперь у my_scriptV3.py есть весь код, который был у my_script.py, а my_script.py теперь является обработчиком версии, который помогает пользователю правильно настроить, какую версию используйте и требует, чтобы это действие выполнялось только один раз и только в том случае, если основным интерпретатором python является python 2, а затем каждый раз, когда он вызывает my_script.py из cmd, он будет использовать предыдущую информацию и снова вызывать my_scriptV3.py без каких-либо дополнительных шагов.

Вот код, который может кому-то помочь (он не оптимизирован):

import os
import sys
import pickle
import getpass
from subprocess import Popen, PIPE, call

python_path = r'C:\Users\{}\Documents\py_config.pkl'.format(getpass.getuser())

if sys.version_info.major < 3:
    check_path = os.path.exists(python_path)
    if check_path is False:
        while True:
            sys.stdout.write('Python 2.x is not supported do you have Python 3.x? [y/n]')
            answer = raw_input()
            sys.stdout.write("\r")
            if answer.lower() not in ['y', 'n', 'yes', 'no']:
                sys.stdout.write("Answer can be y or n. Try again..\n")
                continue
            break

        if answer.lower() in ['y', 'yes']:
            py_versions = {}
            sys.stdout.write('\nSelect Python3 version to use\n')
            p = Popen(['py', '--list'], stdout=PIPE)
            while True:
                line = p.stdout.readline()
                if not line:
                    break
                line = line.strip().strip('-')
                if line.startswith('3'):
                    line = line[:line.find('-')]
                    py_versions.update({len(py_versions): line})
            if not py_versions:
                sys.stdout.write('\nInstall Python 3 to be able to use this framework')
                exit()
            while True:
                options = ""
                for k, v in py_versions.items():
                    options += "[%s] %s\n" % (k,v)
                sys.stdout.write(options)
                answer = raw_input()
                if answer.isdigit() is False:
                    sys.stdout.write("\n Option must be numeric value. Please try again...\n")
                    continue

                selected_option = int(answer)
                if selected_option not in py_versions.keys():
                    sys.stdout.write("\n Option you entered does not exist. Please try again...\n")
                    continue

                py_version = py_versions.get(selected_option)
                if py_version is not None:
                    py_data = {'version': py_version}
                    sys.stdout.write('\nSelected Python version is %s\n' % py_version)
                    sys.stdout.write('\nChecking paths for this Python pleas wait..\n')
                    p = Popen(
                        'py -%s -c "import sys; import os; sys.stdout.write(os.path.dirname(sys.executable))" ' % py_version,
                        stdout=PIPE)
                    lines = p.stdout.readlines()
                    main_path = lines[0]

                    pycon_path = os.path.join(main_path,'Scripts','my_script.py')
                    if os.path.exists(pycon_path) is False:
                        sys.stdout.write("\n Can't locate my_script.py at {0} \n make sure you are using python "
                                         "version where you installed this package then try again...".format(pycon_path))
                        exit()

                    command = 'py -{0} {1}'.format(py_version, pycon_path)
                    py_data.update({'cmd': command})
                    with open(python_path, 'wb') as fw:
                        pickle.dump(py_data, fw)
                    call(command)

                break


        else:
            sys.stdout.write('\nInstall Python 3 to be able to use this framework')
    else:

        with open(python_path, 'rb') as fr:
            data = pickle.load(fr)
            version = data.get('version')
            sys.stdout.write('\nPython version is defined in %s\n'% python_path)
            sys.stdout.write('\nSelected Python version is %s\n' % version)
            cmd = data.get('cmd')
            call(cmd)


else:
    from Scripts.my_scriptv3 import *
    Configuration()
...