一次小折腾:PyCharm 调用 Cygwin Python 找不到 time、sys 等内置模块
1、需求背景
为什么要这样干呢?因为 Python 虽然号称跨平台,但是一些和操作系统相关的函数 API,windows 下也还是只能干瞪眼用不了,比如 import fcntl 这在 windows 下是没法用的,这就给开发测试带来了不便,在两个异构系统上,没法无缝切换 work。因此,能想到的就是利用 windows 上的 Cygwin 模拟 linux,然后 Pycharm 去调用 Cygwin 下的 Python 即可。
2、配置环境变量以及 PyCharm 参数
2.1 环境变量
CYGWIN_HOME=D:Cygwin_64bit
Path=C:ProgramDataOracleJavajavapath;%SystemRoot%system32;%SystemRoot%;%SystemRoot%System32Wbem;%SYSTEMROOT%System32WindowsPowerShellv1.0;f:OpenV**bin;%JAVA_HOME%bin;%SCALA_HOME%bin;%CYGWIN_HOME%lib;%CYGWIN_HOME%bin;%CYGWIN_HOME%usrsbin;%CYGWIN_HOME%libpython2.7;%CYGWIN_HOME%usrincludepython2.7;%CYGWIN_HOME%usrinclude;D:phantomjs-2.0.0-windowsbin;%MINGW_HOME%mingw32bin;D:Kerberosbin;C:Program FilesMITKerberosbin;F:SCRT
PYTHONPATH=%CYGWIN_HOME%lib;%CYGWIN_HOME%bin;%CYGWIN_HOME%usrsbin;%CYGWIN_HOME%libpython2.7;%CYGWIN_HOME%usrincludepython2.7;%PYTHONPATH%
# 以下3个和本文主题无关,备份之用
LIBRARY_PATH=%CYGWIN_HOME%lib
MINGW_HOME=D:C-Free5mingw
C_INCLUDE_PATH=%CYGWIN_HOME%libgccx86_64-pc-cygwin5.3.0;%CYGWIN_HOME%libgccx86_64-pc-cygwin5.3.0includec++;%CYGWIN_HOME%libgccmingw323.4.5include
2.2 设置 pycharm 解释器路径
2.3 测试代码
代码请使用《300行python代码的轻量级HTTPServer实现文件上传下载》来测试,这份的代码的特点是在 windows 下会报错,linux 正常,因为使用了 linux 下特有的模块:fcntl
然而我们却在 IDE 里看到语法报错了:
这是为毛?
sys 和 time 模块居然会找不到???
然后小心翼翼的先 alt + shift + x 执行试试,居然 working 正常!
3、如何解决这个问题
由于想到 sys 和 time 都属于内置模块,可能和 python.exe 这个可执行文件有关,于是先 copy 了一个 windows 版的 python.exe 过去试试,重新加载就没有语法报错的问题了。
但是上面的疑问还是没解决:为什么 time 和 sys 模块找不到居然还能执行成功呢?
第一反应就是找找看 time 在哪里。搜索了 python 安装目录,发现根本就找不到 time.py 或者 time.pyc,然后继续查看系统环境:
import sys
# for i in sys.modules.keys():
# print i
# print sys.path
import time
# print time.__file__
import imp
# print imp.find_module('time')
# print help(imp)
# import datetime
# print datetime.__file__
# D:Cygwin_64bitbinpython2.7.exe F:/sourceDemo/flask/study/flumeFileMonitor/t1.py
# /usr/lib/python2.7/lib-dynload/datetime.dll
import fcntl
print fcntl.__file__
当 解释器是 windows 版本时,time.__file__ 会抛异常,根本就找不到 time 模块路径,是不是很奇怪,那平时咱们 import time 是怎么执行成功的呢?
搜了下 SF 发现了答案:
原来 windows 下的这些内置模块都是 C 写的,是没有 time.__file__ 属性,也就是看不到源码的,而在linux下则会指向一个 .so 文件。
当解释器是 Cygwin 版本时,time.__file__ 结果是:/usr/lib/python2.7/lib-dynload/time.dll
- 也就是说虽然 Pycharm 中加载 windows 版本解释器语法提示不报错,但是 time.__file__ 会抛异常,但这又是正常的,因为内置模块存在只是没有提供这个属性而已。
- 然而 Pycharm 中加载 Cygwin 版本解释器虽然报错提示找不到模块,但是真正执行的时候是没有问题的,因为相应的模块都以 .dll 形式提供了,只是 Pycharm 无法直接静态分析该版本的 python.exe,而导致“看起来找不到内置模块”,因此才会出现了 IDE 静态分析提示错误,但是能执行成功的现象。
- 而且这两个版本的解释器对调用执行基础的模块、函数 都是没有问题的。
至此,我们能看到这两个版本的 python.exe 各有优劣:
- Cygwin 版本可以利用 linux 特性,但是会影响 Pycharm 静态分析功能导致内置模块看起来缺失,和相应的代码提示功能不可用。
- Windows 版本下,Pycharm 的静态分析功能可以给用户提供强大的语法检查和智能代码提示。
但是我们没有办法可以让 Pycharm 既能支持 linux 特性也能拥有内置模块语法检查与代码提示功能。说到底这是一个熊掌与鱼不可兼得的问题。
最后要说下,我还尝试了另一个方案:自己在 Cygwin 下编译 Linux 版 Python 源码,但是和 Cygwin 自带 Python 一样,存在同样的问题。而且编译过程当中还遇到报错了:
File "./setup.py", line 2041, in configure_ctypes
exec f in fficonfig
File "build/temp.cygwin-2.4.1-x86_64-2.7/libffi/fficonfig.py", line 33, in <mo dule>
ffi_sources += ffi_platforms['X86_WIN64']
KeyError: 'X86_WIN64'
Makefile:513: recipe for target 'sharedmods' failed
make: *** [sharedmods] Error 1
解决方案是将第 33 行的 X86_WIN64 改成 X86_64 即可通过编译。
ffi_sources = """
src/prep_cif.c
src/closures.c
""".split()
ffi_platforms = {
'MIPS_IRIX': ['src/mips/ffi.c', 'src/mips/o32.S', 'src/mips/n32.S'],
'MIPS_LINUX': ['src/mips/ffi.c', 'src/mips/o32.S'],
'X86': ['src/x86/ffi.c', 'src/x86/sysv.S', 'src/x86/win32.S'],
'X86_FREEBSD': ['src/x86/ffi.c', 'src/x86/freebsd.S'],
'X86_WIN32': ['src/x86/ffi.c', 'src/x86/win32.S'],
'SPARC': ['src/sparc/ffi.c', 'src/sparc/v8.S', 'src/sparc/v9.S'],
'ALPHA': ['src/alpha/ffi.c', 'src/alpha/osf.S'],
'IA64': ['src/ia64/ffi.c', 'src/ia64/unix.S'],
'M32R': ['src/m32r/sysv.S', 'src/m32r/ffi.c'],
'M68K': ['src/m68k/ffi.c', 'src/m68k/sysv.S'],
'POWERPC': ['src/powerpc/ffi.c', 'src/powerpc/ffi_sysv.c', 'src/powerpc/ffi_linux64.c', 'src/powerpc/sysv.S', 'src/powerpc/ppc_closure.S', 'src/powerpc/linux64.S', 'src/powerpc/linux64_closure.S'],
'POWERPC_AIX': ['src/powerpc/ffi_darwin.c', 'src/powerpc/aix.S', 'src/powerpc/aix_closure.S'],
'POWERPC_FREEBSD': ['src/powerpc/ffi.c', 'src/powerpc/sysv.S', 'src/powerpc/ppc_closure.S'],
'AARCH64': ['src/aarch64/sysv.S', 'src/aarch64/ffi.c'],
'ARM': ['src/arm/sysv.S', 'src/arm/ffi.c'],
'LIBFFI_CRIS': ['src/cris/sysv.S', 'src/cris/ffi.c'],
'FRV': ['src/frv/eabi.S', 'src/frv/ffi.c'],
'S390': ['src/s390/sysv.S', 'src/s390/ffi.c'],
'X86_64': ['src/x86/ffi64.c', 'src/x86/unix64.S', 'src/x86/ffi.c', 'src/x86/sysv.S'],
'SH': ['src/sh/sysv.S', 'src/sh/ffi.c'],
'SH64': ['src/sh64/sysv.S', 'src/sh64/ffi.c'],
'PA': ['src/pa/linux.S', 'src/pa/ffi.c'],
'PA_LINUX': ['src/pa/linux.S', 'src/pa/ffi.c'],
'PA_HPUX': ['src/pa/hpux32.S', 'src/pa/ffi.c'],
}
ffi_sources += ffi_platforms['X86_64']
ffi_cflags = ' -Wall -fexceptions'
说到底文章开头的想法最终也没能行得通,也罢,windows Pycharm 下还是老老实实的用 windows 版 Python 吧,Cygwin 下用 vim 凑合得了~
Refer:
[1] How do I find the location of Python module sources?
http://stackoverflow.com/questions/269795/how-do-i-find-the-location-of-python-module-sources
[2] Error with libffi while installing Python 2.7.5 on Cygwin 64
https://github.com/yyuu/pyenv/issues/61
[3] Re: Unable to compile python 3.3 [Was: Re: Python 3.3 coming soon?]
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 垃圾回收相关概念 Krains 2020-08-06
- 算法—判断字符串是否为IP地址
- 基于SpringBoot的Web前后端分离开发
- 【赵渝强老师】Docker的日志
- 超全递归技巧整理,这次一起拿下递归
- [译] React 测试驱动开发:从用户故事到产品
- 计算机基础之位运算 | 按位取反
- 关于php的ini文件相关操作函数浅析
- PHP中的输出缓冲控制
- SpringCloud微服务:基于Nacos组件,整合Dubbo框架
- [译] 使用 microbundle 打包 TypeScript 组件库
- 3分钟短文 | Laravel 获取模型查询生成的SQL语句
- 基于git的测试用例管理方案
- 【赵渝强老师】MongoDB管理用户的认证机制
- 使用Microsoft Teams Updater执行代码