一次小折腾: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?]
- 桌面白屏(Active故障)修复批处理
- ASM 翻译系列第十三弹:ASM 高级知识 - Forcing the issue
- ASM 翻译系列第十四弹:ASM Internal Rebalancing act
- DIY网站统计:WordPress排除管理员评论及精准友链数的方法
- Linux运维工程师:30道面试题整理
- ASM 翻译系列第十五弹:ASM Internal ASM File Directory
- ASM 翻译系列第十六弹:ASM Internal ASM Active Change Directory
- ASM 翻译系列第十七弹:ASM Internal ASM Disk Directory
- Windows 7下获取System权限
- ASM 翻译系列第十八弹:ASM Internal ASM file number 5
- 菜单式Shell运维脚本调试小记
- 优化Postgres-x2 GTM
- 启用某些Linux发行版的root帐号
- Linux中的完美截图工具:Deepin-ScreenShot
- 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 数组属性和方法
- MapReduce工作笔记——Streaming多路输出
- nuxt.js项目入门配置篇
- 高级综合工具StratusHLS学习笔记(4)
- 论文笔记&翻译——Enhanced LSTM for Natural Language Inference(ESIM)
- Day 5:用两个栈实现队列
- C++核心准则T.42:使用模板别名简化记法并隐藏实现细节
- Python实战——ESIM 模型搭建(keras版)
- MapReduce工作笔记——Job调度参数设置
- 矩阵操作试题(C++/Python)——矩阵元素逆时针旋转90度(升级版)
- Macdown中[toc]无法生成目录解决方法
- Linux实用技巧——mkdir创建多级新目录
- C++核心准则T.43: 定义别名时,using比typedef更好
- C++核心准则T.44:使用函数模板推断类模板参数类型(如果可能)
- python函数——浅拷贝copy()以及深拷贝deepcopy()
- 数据结构算法操作试题(C++/Python)——两数之和