在Python脚本中检查包是否安装的好方法是什么?我知道解释器很容易,但是我需要在脚本中完成它.
我想我可以检查系统中是否有安装过程中创建的目录,但我觉得有更好的方法.我正在尝试确保安装了Skype4Py软件包,如果没有,我会安装它.
我完成检查的想法
我在Python脚本中遇到了一些导入模块的问题.我将尽我所能来描述错误,为什么我遇到它,以及为什么我要用这种特殊的方法来解决我的问题(我将在一秒钟内描述):
假设我有一个模块,我在其中定义了一些实用函数/类,它们引用了将在其中导入此辅助模块的命名空间中定义的实体(让"a"成为这样的实体):
模块1:
def f():
print a
Run Code Online (Sandbox Code Playgroud)
然后我有主程序,其中定义了"a",我想导入这些实用程序:
import module1
a=3
module1.f()
Run Code Online (Sandbox Code Playgroud)
执行程序将触发以下错误:
Traceback (most recent call last):
File "Z:\Python\main.py", line 10, in <module>
module1.f()
File "Z:\Python\module1.py", line 3, in f
print a
NameError: global name 'a' is not defined
Run Code Online (Sandbox Code Playgroud)
过去(两天前,呃)已经提出了类似的问题,并提出了几种解决方案,但我并不认为这些问题符合我的要求.这是我的特定背景:
我正在尝试创建一个连接到MySQL数据库服务器并使用GUI显示/修改数据的Python程序.为清洁起见,我在一个单独的文件中定义了一堆辅助/实用的MySQL相关函数.但是它们都有一个公共变量,我最初在实用程序模块中定义了它,它是MySQLdb模块中的游标对象.后来我意识到应该在主模块中定义游标对象(用于与数据库服务器通信),这样主模块和导入其中的任何东西都可以访问该对象.
最终结果将是这样的:
utilities_module.py:
def utility_1(args):
code which references a variable named "cur"
def utility_n(args):
etcetera
Run Code Online (Sandbox Code Playgroud)
我的主要模块:
program.py:
import MySQLdb, Tkinter
db=MySQLdb.connect(#blahblah) ; cur=db.cursor() #cur is defined!
from …Run Code Online (Sandbox Code Playgroud) 编辑:基于Ulf Rompe的注释,重要的是你使用"1"代替"0",否则你将破坏sys.path.
我已经做了很长一段时间的python(超过一年),我总是很困惑,为什么人们建议你使用sys.path.append()而不是sys.path.insert().让我来证明一下.
假设我正在开发一个名为PyWorkbooks的模块(安装在我的计算机上),但我同时处理一个包含PyWorkbooks的不同模块(比方说PyJob).当我正在使用PyJob时,我发现PyWorkbooks中的错误正在纠正,所以我想导入一个开发版本.
有两种方法可以同时工作(例如,我可以将PyWorkbooks项目放在PyJob中),但有时我仍然需要使用路径.但是,我不能简单地对sys.path.append()PyWorkbooks所在的文件夹执行操作.为什么?因为python会首先找到我安装的PyWorkbooks!
这就是你必须做一个sys.path.insert(1,path_to_dev_pyworkbooks)的原因
综上所述:
sys.path.append(path_to_dev_pyworkbooks)
import PyWorkbooks # does NOT import dev pyworkbooks, imports installed one
Run Code Online (Sandbox Code Playgroud)
要么:
sys.path.insert(1, path_to_dev_pyworkbooks) # based on comments you should use **1 not 0**
import PyWorkbooks # imports correct file
Run Code Online (Sandbox Code Playgroud)
这对我来说已经引起了一些困扰,如果我们(作为一个社区)开始推荐sys.path.insert(1, path),我真的很喜欢它,好像你是手动插入一条路径我认为可以说这是你想要的路径用!
或者我有什么不对劲?这个问题有时会困扰我,我希望它在公开场合!
在Python中,一旦我在解释器会话中导入模块X import X,并且模块在外部更改,我可以重新加载模块reload(X).然后,在我的翻译会话中可以使用这些更改.
我想知道当我从模块X导入组件Y时是否也可以这样做from X import Y.
该语句reload Y不起作用,因为Y本身不是模块,而只是模块内部的一个组件(在本例中是一个类).
是否可以在不离开解释器会话(或导入整个模块)的情况下重新加载模块的各个组件?
编辑:
为了澄清,问题是从模块X导入类或函数Y并重新加载更改,而不是从包X中重新模块Y.
另一位开发人员和我不同意是否应该使用PYTHONPATH或sys.path来允许Python在用户(例如,开发)目录中查找Python包.
我们有一个具有典型目录结构的Python项目:
Project
setup.py
package
__init__.py
lib.py
script.py
Run Code Online (Sandbox Code Playgroud)
在script.py中,我们需要这样做import package.lib.当软件包安装在site-packages中时,script.py可以找到package.lib.
但是,当从用户目录工作时,还需要做其他事情.我的解决方案是将我的PYTHONPATH设置为包含"〜/ Project".另一位开发人员希望将这行代码放在script.py的开头:
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
Run Code Online (Sandbox Code Playgroud)
这样Python就可以找到本地副本了package.lib.
我认为这是一个坏主意,因为这行只对开发人员或从本地副本运行的人有用,但我不能说明为什么这是一个坏主意.
我们应该使用PYTOHNPATH,sys.path,还是要么?
在运行python脚本时,我遇到了这个错误
from lxml import etree
ImportError: No module named lxml
Run Code Online (Sandbox Code Playgroud)
现在我尝试安装lxml
sudo easy_install lmxl
Run Code Online (Sandbox Code Playgroud)
但它给了我以下错误
Building lxml version 2.3.beta1.
NOTE: Trying to build without Cython, pre-generated 'src/lxml/lxml.etree.c' needs to be available.
ERROR: /bin/sh: xslt-config: not found
** make sure the development packages of libxml2 and libxslt are installed **
Run Code Online (Sandbox Code Playgroud)
使用libxslt的构建配置
src/lxml/lxml.etree.c:4: fatal error: Python.h: No such file or directory
compilation terminated.
error: Setup script exited with error: command 'gcc' failed with exit status 1
Run Code Online (Sandbox Code Playgroud) 我有一个充满脚本的目录(比方说project/bin).我还有一个库project/lib,希望脚本自动加载它.这是我通常在每个脚本的顶部使用的内容:
#!/usr/bin/python
from os.path import dirname, realpath, sep, pardir
import sys
sys.path.append(dirname(realpath(__file__)) + sep + pardir + sep + "lib")
# ... now the real code
import mylib
Run Code Online (Sandbox Code Playgroud)
这有点麻烦,丑陋,必须在每个文件的开头粘贴.有一个更好的方法吗?
我真正希望的是这样的顺利:
#!/usr/bin/python
import sys.path
from os.path import pardir, sep
sys.path.append_relative(pardir + sep + "lib")
import mylib
Run Code Online (Sandbox Code Playgroud)
或者甚至更好,当我的编辑(或其他有提交访问权限的人)决定重新排序导入作为其清理过程的一部分时,这些东西不会破坏:
#!/usr/bin/python --relpath_append ../lib
import mylib
Run Code Online (Sandbox Code Playgroud)
这不会直接移植到非posix平台,但它会保持干净.
PEP8表明:
应按以下顺序对导入进行分组:
- 标准库导入
- 相关的第三方进口
- 本地应用程序/库特定导入
您应该在每组导入之间添加一个空行.
有没有一种方法来检查,如果该标准在使用静态代码分析工具包违反任何地方,比如pylint,pyflakes,pychecker,pep8?
违规示例:
from my_package import my_module
from django.db import models
import os
Run Code Online (Sandbox Code Playgroud)
正确的导入方式:
import os
from django.db import models
from my_package import my_module
Run Code Online (Sandbox Code Playgroud) 我注意到今天我想解释一些奇怪的东西.我不是100%肯定如何将这个问题作为一个问题,所以谷歌是不可能的.由于某些奇怪的原因,日志记录模块无法访问模块logging.handlers.如果你不相信我,请亲自尝试一下:
>>> import logging
>>> logging.handlers
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'handlers'
>>> import logging.handlers
>>> logging.handlers
<module 'logging.handlers' from '/usr/lib/python2.6/logging/handlers.pyc'>
Run Code Online (Sandbox Code Playgroud)
谁能解释为什么会这样?
尝试导入OpenCV时,使用import cv2我得到以下错误:
/usr/local/lib/python2.7/dist-packages/cv2/__init__.py in <module>()
7
8 # make IDE's (PyCharm) autocompletion happy
----> 9 from .cv2 import *
10
11 # wildcard import above does not import "private" variables like __version__
ImportError: libSM.so.6: cannot open shared object file: No such file or directory
Run Code Online (Sandbox Code Playgroud)
不确定如何解决这个问题 - 尝试使用谷歌新的Colaboratory工具.笔记本电脑在这里:https://drive.google.com/file/d/0B7-sJqBiyjCcRmFkMzl6cy1iN0k/view?usp=sharing
python ×10
python-import ×10
pythonpath ×2
importerror ×1
lxml ×1
mysql-python ×1
namespaces ×1
opencv ×1
package ×1
path ×1
pep8 ×1
python-2.6 ×1
skype ×1
sys.path ×1