一次小折腾: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:\ProgramData\Oracle\Java\javapath;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;f:\OpenVPN\bin;%JAVA_HOME%\bin;%SCALA_HOME%\bin;%CYGWIN_HOME%\lib;%CYGWIN_HOME%\bin;%CYGWIN_HOME%\usr\sbin;%CYGWIN_HOME%\lib\python2.7;%CYGWIN_HOME%\usr\include\python2.7;%CYGWIN_HOME%\usr\include;D:\phantomjs-2.0.0-windows\bin;%MINGW_HOME%\mingw32\bin;D:\Kerberos\bin;C:\Program Files\MIT\Kerberos\bin;F:\SCRT

PYTHONPATH=%CYGWIN_HOME%\lib;%CYGWIN_HOME%\bin;%CYGWIN_HOME%\usr\sbin;%CYGWIN_HOME%\lib\python2.7;%CYGWIN_HOME%\usr\include\python2.7;%PYTHONPATH%

# 以下3个和本文主题无关,备份之用
LIBRARY_PATH=%CYGWIN_HOME%\lib
MINGW_HOME=D:\C-Free5\mingw
C_INCLUDE_PATH=%CYGWIN_HOME%\lib\gcc\x86_64-pc-cygwin\5.3.0;%CYGWIN_HOME%\lib\gcc\x86_64-pc-cygwin\5.3.0\include\c++;%CYGWIN_HOME%\lib\gcc\mingw32\3.4.5\include

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_64bit\bin\python2.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?]

http://bit.ly/1TdHAcs

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏木宛城主

基于Socket的网络聊天室编程(第一版)

一:什么是套接字 在网络编程中最常用的方案便是Client/Server (客户机/服务器)模型。在这种方案中客户应用程序向服务器程序请求服务。一个服务程序通常...

2905
来自专栏落影的专栏

编译与链接过程的思考

前言 最近遇到一个错误,如下 ? 在解决过程中,回顾了很多知识,于是有了这篇文章。 关键词:预处理、编译、汇编、链接、动态链接库、静态链接库、真机调...

5209
来自专栏酷玩时刻

支付宝Wap支付你了解多少?

为了方便开发者生成一对RSA密钥支付宝提供一键生成工具,具体如何生成与配置密钥详见签名专区。

3652
来自专栏jessetalks

Membership三步曲之入门篇 - Membership基础示例

Membership类成员介绍   一般来讲我们的网站要实现的与用户相关的最基本功能包括:注册,登录,修改用户资料和密码。Membership为我们提供了以下...

3226
来自专栏菩提树下的杨过

Flash/Flex学习笔记(53):利用FMS快速创建一个文本聊天室

先来看客户端fla的构成: 第一帧:登录界面 ? 第一帧的代码: import flash.events.MouseEvent; import com.adob...

2109
来自专栏开发技术

spring集成mybatis实现mysql读写分离

       在网站的用户达到一定规模后,数据库因为负载压力过高而成为网站的瓶颈。幸运的是目前大部分的主流数据库都提供主从热备功能,通过配置两台数据库主从关系,...

1561
来自专栏更流畅、简洁的软件开发方式

【开源】QuickPager ASP.NET2.0分页控件 v2.0.0.2版本。

下载地址:http://files.cnblogs.com/jyk/Page2.0.0.2_080701.rar 这回只有 dll文件。请把包里的文件拷贝到...

2076
来自专栏james大数据架构

资源等待类型sys.dm_os_wait_stats

动态管理视图  sys.dm_os_wait_stats  返回执行的线程所遇到的所有等待的相关信息。可以使用该聚合视图来诊断 SQL Server 以及特定查...

2297
来自专栏刘望舒

Android系统启动流程(四)Launcher启动过程与系统启动流程

前言 此前的文章我们学习了init进程、Zygote进程和SyetemServer进程的启动过程,这一篇文章我们就来学习Android系统启动流程的最后一步:L...

2508
来自专栏along的开发之旅

OkHttp使用完全教程

上一节我们讲述了Http请求的过程, 这一节我们就讲述下OkHttp是怎么完成Http请求的. 为了更好的理解OKHttp,强烈推荐先看一下http的整个...

4513

扫码关注云+社区

领取腾讯云代金券