Python36\Scripts 从错误的 python 版本开始
Python36\Scripts starts on wrong python version
所以我制作了一个包,其中包含一个 python 文件,该文件在安装过程中进入 Python36\Scripts。但是在 WinOS 上,我有 3 个全局 python 解释器。
主要是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 under C:\Python36\Scripts\my_script.py
所以现在你知道我在 cmd my_script.py 中写的问题在哪里,它会 运行 它超过 python2.7 会引发异常,因为它是不 python2.7 友好。
在 UNIX 中,使用 shebang 行可以轻松解决。
如何使用 python3.6 解释器调用 my_script.py。
在你回答之前我试过这个:
cmd 处于管理员模式
py -3.6 my_script.py 启动会导致 [Errno 2] No such file or directory
包的结构:
- my_package
- my_package
- __init_.py
- settings.py
- 脚本
- __init_.py
- my_script.py
- 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 *
调用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
个文件时使用的exe,并且一次只能注册一个解释器
- 目录
c:\python36\scripts
必须在您的路径上
Windows 不使用 #!
shebang "protocol" 将执行文件的命令放在文件的第一行
我为这个问题做了一个解决方法,它会很好地工作。现在我没有一个脚本,而是 my_script.py 和 my_scriptV3.py... 现在 my_scriptV3.py 拥有 my_script.py 拥有的所有代码并且 my_script.py 现在是版本帮助用户正确设置要使用的版本的处理程序,并且仅在主 python 解释器为 python 2 的情况下才需要该操作一次,以后每次从 cmd 调用 my_script.py 时它将使用以前的信息并再次调用 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()
所以我制作了一个包,其中包含一个 python 文件,该文件在安装过程中进入 Python36\Scripts。但是在 WinOS 上,我有 3 个全局 python 解释器。
主要是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 under C:\Python36\Scripts\my_script.py
所以现在你知道我在 cmd my_script.py 中写的问题在哪里,它会 运行 它超过 python2.7 会引发异常,因为它是不 python2.7 友好。
在 UNIX 中,使用 shebang 行可以轻松解决。 如何使用 python3.6 解释器调用 my_script.py。
在你回答之前我试过这个:
cmd 处于管理员模式
py -3.6 my_script.py 启动会导致 [Errno 2] No such file or directory
包的结构:
- my_package
- my_package
- __init_.py
- settings.py
- 脚本
- __init_.py
- my_script.py
- setup.py
- my_package
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 *
调用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
个文件时使用的exe,并且一次只能注册一个解释器 - 目录
c:\python36\scripts
必须在您的路径上
Windows 不使用 #!
shebang "protocol" 将执行文件的命令放在文件的第一行
我为这个问题做了一个解决方法,它会很好地工作。现在我没有一个脚本,而是 my_script.py 和 my_scriptV3.py... 现在 my_scriptV3.py 拥有 my_script.py 拥有的所有代码并且 my_script.py 现在是版本帮助用户正确设置要使用的版本的处理程序,并且仅在主 python 解释器为 python 2 的情况下才需要该操作一次,以后每次从 cmd 调用 my_script.py 时它将使用以前的信息并再次调用 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()