pythongevent安装
A. centos6.5 安装goAgent 使用python需要安装gevent但是安装后仍没用
gevent 还需要先装 greenlet 和 Cython 才能奏效。
B. windows下怎么安装Gevent
使用gevent,可以对并发多个http请求的爬虫程序进行很好的优化, 缺点是,安装相对麻烦,这个包依赖于libevent,在windows下面用easy_install直接安装是不行的,必须用源代码包
wget http://pypi.python.org/packages/source/g/gevent/gevent-0.13.8.tar.gz
tar zxvf gevent-0.13.8.tar.gz
cd gevent
里面有个fetch_libevent.py 用来帮你下载libevent依赖
python fetch_libevent.py
python setup.py build
python setup.py install
这样可以安装成功,如果还不行,只能使用大杀器了windows下安装python模块的终极解决方案。
C. python怎么导入模块gevent
Python通过yield提供了对协程的基本支持,但是不完全。而第三方的gevent为Python提供了比较完善的协程支持。
gevent是第三方库,通过greenlet实现协程,其基本思想是:
当一个greenlet遇到IO操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。
D. python的安装包最后一直初始化怎么解决
当遇到无法导入某个python模块时,可能会是没有安装某个模块,也有可能是某模块在加载过程中失败,也有可能是陷入了循环导入的问题。本文详细解释了这个问题。
1. 模块未安装或者路径不对
ImportError: No mule named myMole
有两种可能,一是该模块没有安装,一般可以用
pip install %mole_name%
来解决。注意有时候模块安装包名并不等于要导入的模块名。这种情况下可以通过pip search | list命令来尝试找到正确的包。
另一种情况就是包虽然安装了,但当前运行的程序加载的路径有错。python运行时将从以下位置尝试加载python moles:
* 当前目录
* 环境变量$PYTHONPATH所指示的值,这是一个由“:”分隔的字符串,各个子字符串都是文件系统的一个路径。
* 标准库目录,如dist-site-packages下的模块。
* 在.pth文件中指定的路径,如果存在.pth文件的话。
可以使用以下方式来查看python运行时的包含路径:
?
12
import sysprint(sys.path)
在运行出错的脚本装头部加上这一段代码,然后在控制台中查看打印出来的python类库路径,检查安装包是否已包含在上述路径中。
***可以通过下面的方式将未包含在路径中的模块临时包含进来:***
sys.path.append("path/to/mole")
另外,还可以在shell窗口中查看当前的python包含路径:
echo $PYTHONPATH
2. 无法导入已存在的模块
如果要导入的模块包含了native代码,并且native代码加载(初始化)失败时,就会导致这种错误。使用ssl,
gevent等涉及native的模块时,如果对应的native程序并未安装,则会出现这样的错误。
另一种错误情况是,使用相对路径导入时,父模块还未导入成功。见下面的代码:
?
12345
main.pymypackage/ __init__.pymymole.pymyothermole.py
mymole.py如下所示:
?
123456789101112
#!/usr/bin/env python3 # Exported functiondef as_int(a): return int(a) # Test function for mole def _test(): assert as_int('1') == 1 if __name__ == '__main__': _test()
以及myothermole代码如下所示:
?
1234567891011121314
#!/usr/bin/env python3 from .mymole import as_int # Exported functiondef add(a, b): return as_int(a) + as_int(b) # Test function for mole def _test(): assert add('1', '1') == 2 if __name__ == '__main__': _test()
如果执行mypackage/myothermole,则会报以下错误:
Traceback (most recent call last):
File "myothermole.py", line 3, in
<mole>
from .mymole import as_int
SystemError: Parent mole
'' not loaded, cannot perform relative import
[这篇文章](#Relative imports in
Python 3)给出了更详细的解答。
3. 循环导入
这种错误称之为"circular (or cyclic) imports"。是python独有的一种导入错误,在象java这样的语言中就不存在。
假设有如下两个文件,a.py和b.py:
?
1234567
#a.pyprint "a in"import sysprint "b imported: %s" % ("b" in sys.moles, )import bprint "a out"print b.x
以及:
?
12345
#b.pyprint "b in"import aprint "b out"x = 3
执行python a.py,将得到以下结果:
?
123456789101112131415
$ python a.pya in b imported: Falseb ina inb imported: Truea outTraceback (most recent call last): File "a.py", line 4, in <mole> import b File "/home/shlomme/tmp/x/b.py", line 2, in <mole> import aFile "/home/shlomme/tmp/x/a.py", line 7, in <mole> print b.xAttributeError: 'mole' object has no attribute 'x'
出现这种情况的原因是产生了循环导入。循环导入,以及在导入过程中python进行了加锁操作,最终导致在模块b未导入完成时就引用了其中的名字。
判断导入错误是否是因为循环导入引起的,主要看堆栈中是否出现两次重复的导入。比如上述堆栈中a.py出现两次,因此可以判断是这个文件引起的循环导入。
要解决这个问题,可以把模块看成一种资源,对所有要引入的模块进行编号,再按静态资源排序法顺次导入,就可以避免循环导入。
E. gevent怎么编译
在gevent中主要使用Greenlet,给Python提供一个轻量级的协同程序,作为一个C的扩展模
块.Greenlets主程序运行的所有系统进程是合理安排的.
这不同于任何multiprocessing或者multithreading提供的库和POSIX线程,这是真正的并行多处理器或多线程库提供真正的并
行结构
首先感谢https://maskv.com/technology/192.html作者给我的帮助我参考老方法编译gevent1.0rc2成功但是无法运行Goagent最新版只能运行2.17原因就是缺少python2.7的支持现在博主给出啦方法搬过来方便大家
Tomato中python2.7+gevent1.0rc2环境的搭建
之前因为没有搜索到在Tomato中编译安装gevent的教程,就自己琢磨出来Tomato中python2.6+gevent0.13.8环境的搭建方法(点击这里查看),
文章发布之后收到了众多的反馈。虽然Python官网当中的gevent最新版本为0.13.8,但Github上的gevent源码已经更新到了
1.0rc2,最新版的Goagent本地客户端也集成的是gevent1.0rc2,在整合了一些反馈之后,在自己的路由器上成功更新了python和
gevent。
首先卸载路由当中的python2.6及其相关组件,运行:
ipkg -force-removal-of-dependent-packages remove python26
rm -rf /opt/local/lib/python2.6 #若挂载路径非/opt请自行修改
rm -rf /opt/lib/python2.6
之后更新、安装所需要的依赖包:
ipkg update
ipkg upgrade
ipkg install busybox buildroot make grep openssl openssl-dev libuclibc++ wget-ssl python27 py27-setuptools
安装完成之后,我们要修复几个py27-setuptools当中的小错误。
首先easy_install的安装路径莫名其妙的指向了python2.5,不知是否只有我遇到了这个问题。修改 /opt/lib/python2.7/distutils/distutils.cfg 文件,将
1
site-dirs = /opt/local/lib/python2.5/site-packages
修改为
1
site-dirs = /opt/local/lib/python2.7/site-packages
其次easy_install的安装临时目录指向了/tmp目录,会造成安装某些组件时tmp剩余空间不足而导致的安装失败,我们要手动将其指定到挂载的U盘当中。
在/opt中创建tmp文件夹,修改 /opt/lib/python2.7/site-packages/setuptools/command/easy_install.py 文件,找到412行:
1
tmpdir = tempfile.mkdtemp(prefix="easy_install-")
将其修改为:
1
tmpdir = tempfile.mkdtemp(prefix="easy_install-",dir="/opt/tmp")
然后就可以使用easy_install安装greenlet与cython了(此步骤花费时间奇长无比):
easy_install-2.7 greenlet
easy_install-2.7 cython
ln -s /opt/local/bin/cygdb /opt/bin/cygdb
ln -s /opt/local/bin/cython /opt/bin/cython
之后下载gevent:
cd /opt
/opt/bin/wget https://github.com/downloads/Sit ... event-1.0rc2.tar.gz --no-check-certificate
tar zxvf gevent-1.0rc2.tar.gz
cd gevent-1.0rc2
直接编译会报错,因为使用了mips2的sync指令,在Goagent的issues上找到了答案。心得编译前记得开启虚拟内存
修改 /libev/ev.c 文件,找到604行的:参考https://code.google.com/p/goagent/issues/detail?id=7823
1
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("sync" : : : "memory")
修改为:
#define ECB_MEMORY_FENCE __asm__ __volatile__ (".set mips2; sync; .set mips0": : :"memory")
执行
python2.7 setup.py install
下载并安装pyOpenSSL
cd /opt
wget http://pypi.python.org/packages/source/p/pyOpenSSL/pyOpenSSL-0.12.tar.gz
tar zxvf pyOpenSSL-0.12.tar.gz
cd pyOpenSSL-0.12
python2.7 setup.py install
安装结束之后,运行Goagent可能会提示.python-eggs错误,我们可以手动指定缓存目录。
修改Goagent的proxy.py文件,在:
1
import os
下一行添加:
1
os.environ['PYTHON_EGG_CACHE'] = '/opt/.python-eggs'
或者可以将 gevent-1.0rc2-py2.7-linux-mips.egg 解包:
cd /opt/local/lib/python2.7/site-packages
mv gevent-1.0rc2-py2.7-linux-mips.egg gevent-1.0rc2-py2.7-linux-mips.egg.zip
mkdir gevent-1.0rc2-py2.7-linux-mips.egg
cd gevent-1.0rc2-py2.7-linux-mips.egg
unzip /opt/local/lib/python2.7/site-packages/gevent-1.0rc2-py2.7-linux-mips.egg.zip
再次运行Goagent,应该不会再有错误提示了。
F. python解释器中gevent出现错误怎么解决
解决方法:重新安装gevent以及依赖
pip3 install -U --force-reinstall --no-binary :all: gevent
G. python协程gevent怎么用
在学习gevent之前,你肯定要知道你学的这个东西是什么。
官方描述gevent
gevent is a coroutine-based Python networking library that uses greenlet to provide a high-level synchronous API on top of the libev event loop.
翻译:gevent是一个基于协程的Python网络库。我们先理解这句,也是这次学习的重点——协程。
wiki描述协程
与子例程一样,协程也是一种程序组件。相对子例程而言,协程更为一般和灵活,但在实践中使用没有子例程那样广泛。子例程的起始处是惟一的入口点,一旦退出即完成了子例程的执行,子例程的一个实例只会返回一次;协程可以通过yield来调用其它协程。通过yield方式转移执行权的协程之间不是调用者与被调用者的关系,而是彼此对称、平等的。协程允许多个入口点,可以在指定位置挂起和恢复执行。
没看懂?没关系,我也没看懂,不过算是有点线索:子例程。
子例程
过程有两种,一种叫子例程(Subroutine),通常叫Sub;另一种叫函数(Function)。底层实现机制是一样的,区别在于,Sub只执行操作,没有返回值;Function不但执行操作,并且有返回值。用过VB的应该会比较清楚这点。(原谅我用了网络)说到底子例程就是过程,我们一般叫它函数。
说到函数,我就想吐槽了,不明白为什么要叫函数。很多时候我们写一个函数是为了封装、模块化某个功能,它是一个功能、或者说是一个过程。因为它包含的是类似于流程图那样的具体逻辑,先怎样做,然后怎样做;如果遇到A情况则怎样,如果遇到B情况又怎样。个人觉得还是叫过程比较好,叫做函数就让人很纠结了,难道因为回归到底层还是计算问题,出于数学的角度把它称为函数?这个略坑啊!为了符合大家的口味,我还是称之为函数好了(其实我也习惯叫函数了%>_
讲到函数,我们就往底层深入一点,看看下面的代码:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def a():
print "a start"
b()
print "a end"
def b():
print "b start"
c()
print "b end"
def c():
print "c start"
print "c end"
if __name__ == "__main__":
a()
a start
b start
c start
c end
b end
a end
对于这样的结果大家肯定不会意外的。每当函数被调用,就会在栈中开辟一个栈空间,调用结束后再回收该空间。
假设一个这样的场景:有个讲台,每个人都可以上去发表言论,但是每次讲台只能站一个人。现在a在上面演讲,当他说到“大家好!”的时候,b有个紧急通知要告诉大家,所以a就先下来让b讲完通知,然后a再上讲台继续演讲。如果用函数的思想模拟这个问题,堆栈示意图是这样的:
那什么东西有这样的能力呢?我们很快就可以想到进程、线程,但是你真的想使用进程、线程如此重量级的东西在这么简单的程序上吗?野蛮的抢占式机制和笨重的上下文切换!
还有一种程序组件,那就是协程。它能保留上一次调用时的状态,每次重新进入该过程的时候,就相当于回到上一次离开时所处逻辑流的位置。协程的起始处是第一个入口点,在协程里,返回点之后是接下来的入口点。协程的生命期完全由他们的使用的需要决定。每个协程在用yield命令向另一个协程交出控制时都尽可能做了更多的工作,放弃控制使得另一个协程从这个协程停止的地方开始,接下来的每次协程被调用时,都是从协程返回(或yield)的位置接着执行。
从上面这些你就可以知道其实协程是模拟了多线程(或多进程)的操作,多线程在切换的时候都会有一个上下文切换,在退出的时候将现场保存起来,等到下一次进入的时候从保存的现场开始,继续执行。
看下协程是怎样实现的:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import random
from time import sleep
from greenlet import greenlet
from Queue import Queue
queue = Queue(1)
@greenlet
def procer():
chars = ['a', 'b', 'c', 'd', 'e']
global queue
while True:
char = random.choice(chars)
queue.put(char)
print "Proced: ", char
sleep(1)
consumer.switch()
@greenlet
def consumer():
global queue
while True:
char = queue.get()
print "Consumed: ", char
sleep(1)
procer.switch()
if __name__ == "__main__":
procer.run()
consumer.run()
应用场景
我们一直都在大谈协程是什么样一个东西,却从没有提起协程用来干嘛,这个其实大家分析一下就能够知道。从上面的生产者——消费者问题应该能看出,它分别有两个任务,假设交给两个人去执行,但每次只能允许一个人行动。当缓冲区满的时候,生产者是出于等待状态的,这个时候可以将执行任务的权利转交给消费者,当缓冲区空得时候,消费者是出于等待状态的,这个时候可以将执行任务的权利转交给生产者,是不是很容易联想到多任务切换?然后想到线程?最后想到高并发?
但同学们又会问,既然有了线程为什么还要协程呢?因为线程是系统级别的,在做切换的时候消耗是特别大的,具体为什么这么大等我研究好了再告诉你;同时线程的切换是由CPU决定的,可能你刚好执行到一个地方的时候就要被迫终止,这个时候你需要用各种措施来保证你的数据不出错,所以线程对于数据安全的操作是比较复杂的。而协程是用户级别的切换,且切换是由自己控制,不受外力终止。
总结
协程其实模拟了人类活动的一种过程。例如:你准备先写文档,然后修复bug。这时候接到电话说这个bug很严重,必须立即修复(可以看作CPU通知)。于是你暂停写文档,开始去填坑,终于你把坑填完了,你回来写文档,这个时候你肯定是接着之前写的文档继续,难道你要把之前写的给删了,重新写?这就是协程。那如果是子例程呢?那你就必须重新写了,因为退出之后,栈帧就会被弹出销毁,再次调用就是开辟新的栈空间了。
总结:协程就是用户态下的线程,是人们在有了进程、线程之后仍觉得效率不够,而追求的又一种高并发解决方案。为什么说是用户态,是因为操作系统并不知道它的存在,它是由程序员自己控制、互相协作的让出控制权而不是像进程、线程那样由操作系统调度决定是否让出控制权。
H. 在树莓派上安装python的gevent失败不是此平台支持的车轮
你安装的不是Arm架构的wheel,搜索一下python for arm或python for arm64来了解一下。
I. Win8.1 64位系统,python3.4 怎么安装gevent成功后不能用
windows安装这个太麻烦了:①先装VS,里面要勾选上"编程语言"包,这样就能找到vsvarsall.bat了
②然而scrapy还依赖其他一些包,所以还要安装Lxml。
下载完以后到命令行输入:pip install lxml-3.5.0-cp35-none-win_amd64.whl(或者下载的32位的名字就变一下)③再到命令行:pip install scrapy,安装成功了TT
令:我的是win10系统,python3.5。本人小白一只><
参考资料:安装指南 — Scrapy 0.24.1 文档
①然而后来发现还是用不了,跑不了他的Demo。提示没有"_win32stdio"。所以上StackOverflow查了一下,说Python3.5没有这个库。后来也发现人家Scrapy官网说不支持Python3。
②所以我又安装了Python2.7,然后pip install scrapy的时候,他又提示要装Visual C++ Compiler for Python 2.7。然而我看了一下这个的说明,不支持win10(win8.1应该可以吧)。反正后续我就没再搞了TT
③所以我就转战Ubuntu了。因为自带Python2.7.6,所以不到半小时就搞定了。Scrapy给的Demo也能跑了。
结论:所以还是别用windows了
J. python gevent怎么安装
gevent是第三方库,从https://pypi.python.org/pypi/gevent/#downloads下载安装,在下载文件目录下,使用 命令:pip install xxx.whl 安装即可。