Antkillerfarm Hacking V8.0

language » Python(四)

2019-07-07 :: 7465 Words

Python

如何通过需认证的代理获取HTTP网页

Python内置的urllib和urllib2模块都可用于获取HTTP网页,但使用范围是不同的。urllib只支持HTTP 0.9和HTTP 1.0,所以如果只是使用代理可以使用urllib.FancyURLopener类,如果该代理还需要认证的话urllib就不行了。因为代理认证是HTTP 1.1中引入的。

这时可以考虑使用urllib2模块。代码如下:

import urllib2
l_proxy_info = {
'user' : 'user',
'pass' : 'pass',
'host' : 'host',
'port' : 3128
}

l_proxy_support = urllib2.ProxyHandler({"http" : "http://%(user)s:%(pass)s@%(host)s:%(port)d" % l_proxy_info})
l_opener = urllib2.build_opener(l_proxy_support, urllib2.HTTPHandler)

urllib2.install_opener(l_opener)
usock = urllib2.urlopen('http://www.sohu.com')

Requests

上一小节大概写作于2008年,已经10年了,urllib3都出来了。

Requests是Python语言编写,基于urllib3,采用Apache2 Licensed开源协议的HTTP库。

参考:

https://mp.weixin.qq.com/s/a4mGDzKdEs7-tAPsfyL29w

Python Requests库使用指南

https://mp.weixin.qq.com/s/cyG_TpPA9eyzG70VT2m2Ww

Requests的基本用法

Gunicorn

Gunicorn是一个高效的Python WSGI Server,地位相当于Java中的Tomcat。

官网:

http://gunicorn.org/

参考:

http://www.cnblogs.com/ArtsCrafts/p/gunicorn.html

Gunicorn快速入门

多线程 & 同步 & 异步

python异步并发模块concurrent.futures,主要用来实现多线程和多进程的异步并发。

代码示例:

from concurrent import futures

def test(num):
    import time
    return time.ctime(),num

with futures.ThreadPoolExecutor(max_workers=1) as executor:
    future = executor.submit(test,1)
    print future.result()

>>>
('Tue Jan 17 15:23:10 2017', 1)

如果是多进程的话,可使用ProcessPoolExecutor。由于python是解释语言的关系,多线程设计基本就是残废状态,因此,通常情况下,不要使用多线程,请使用多进程

参考:

http://lovesoo.org/analysis-of-asynchronous-concurrent-python-module-concurrent-futures.html

python异步并发模块concurrent.futures简析

https://mp.weixin.qq.com/s/QIfxxY6z7y77RDE_8gDEIg

并行运算Process Pools

http://www.cnblogs.com/Python666/p/7506546.html

Python单例模式

https://mp.weixin.qq.com/s/tJsdM-4q_RC-5AhTw3y49w

schedule使用进阶

https://mp.weixin.qq.com/s/fwa3cbDI0fIjjztA60XuUQ

同步与异步Python有何不同?

https://mp.weixin.qq.com/s/0tLI_UNhpD-UPa9o206xFA

为什么Python多线程无法利用多核

https://mp.weixin.qq.com/s/6zVU6i75hZ3ZXZAmW0G5Mw

非常适合小白的Asyncio教程

https://mp.weixin.qq.com/s/nHIQ5uwxZM-9DbSu_jL6DQ

异步Python比同步Python快在哪里?

https://mp.weixin.qq.com/s/0MMUTp_-JF97inzeJd4j1g

详解如何用Multiprocessing进行并行计算

mypy

mypy是Dropbox公司编写的一个针对python语言的静态类型检查工具。

官网:

http://www.mypy-lang.org/

参考:

https://mp.weixin.qq.com/s/dBK8x_WajI2A3L5v6OQEgA

四年完成400万行Python代码检查,甚至顺手写了个编译器

glob

glob的历史可以追溯到早期的UNIX系统。用它可以查找符合特定规则的文件路径名。

参考:

https://blog.csdn.net/csapr1987/article/details/7469769

python glob模块

https://mp.weixin.qq.com/s/suUXM4Tdj6ekKQWC0g04Yg

glob-被忽略的python超强文件批量处理模块

PLY

Python Lex-Yacc是一个python版本的lex/yacc实现。

官网:

http://www.dabeaz.com/ply/

参考:

https://blog.csdn.net/feixiaoxing/article/details/79123776

python编程(ply库)

https://blog.csdn.net/chosen0ne/article/details/8077880

Python语法解析器PLY——lex and yacc in Python

JPype

JPype是一个能够让python代码方便地调用Java代码的工具。官网:

https://sourceforge.net/projects/jpype/

参考:

http://blog.csdn.net/niuyisheng/article/details/9002926

JPype:实现在python中调用JAVA

http://www.cnblogs.com/yu-zhang/p/3817024.html

python调用java程序–jpype

SWIG

Simplified Wrapper and Interface Generator可以为C/C++的库生成其他高级脚本语言的Wrapper。

官网:

http://swig.org/

PLY和SWIG的作者都是David Beazley。

David M. Beazley,犹他大学博士。IEEE Gordon Bell Prize(1993,1998)。先后在Los Alamos和University of Chicago工作执教。超算领域专家。python语言核心开发者。

SLY

Sly Lex Yacc是David Beazley的新作,号称新一代的PLY。

官网:

https://sly.readthedocs.io/en/latest/

Cython

和SWIG功能类似的替代品。

官网:

https://cython.org/

示例:

https://github.com/antkillerfarm/antkillerfarm_crazy/tree/master/python/cython

编译:

python setup.py build_ext --inplace

运行:

>import hello
>hello.say_hello()

参考:

https://mp.weixin.qq.com/s/ODA74xgoS8X1HFxp4BfshQ

如何将Python自然语言处理速度提升100倍:用spaCy/Cython加速NLP

https://mp.weixin.qq.com/s/1Iyhsp5-2DyTfOb0JzqLZg

比Python快100倍,利用spaCy和Cython实现高速NLP项目

https://mp.weixin.qq.com/s/l-zmvQvmosw81G1wFCIDbQ

用Cython造个轮子

.pyc & .pyx & .pyd

.pyc: 编译好的二进制文件。

.pyx: python的c扩展文件,代码要符合cython的规范

.pyd: 编译好的cython动态库,仅在Windows平台有,Linux平台生成.so文件。

参考:

https://blog.csdn.net/sislcb/article/details/4002414

py文件编译为pyc

https://www.cnblogs.com/kaituorensheng/p/4452881.html

Cython学习

https://mp.weixin.qq.com/s/_fi4fpfN8Whe7_ZpkPL0tA

怎么给Python写C扩展?

https://mp.weixin.qq.com/s/eqNaX0YorcaMN8D9lnQprw

简单上手一波Cython

http://gashero.yeax.com/?p=38

使用C/C++扩展Python

Pythran

Pythran是一个transpiler,可以把Python的prototype转到C++。

官网:

https://pythran.readthedocs.io/en/latest/

参考:

https://mp.weixin.qq.com/s/hJGaREpBP0j7rqCXSZQMvA

把Python自动翻译成C++

pybind11

pybind11可以在C++11和Python之间建立互操作的关系,而且还是个header-only的方案。

pybind11的灵感来源于Boost.Python,但是后者属于Boost的一部分,使用起来太笨重。

官网:

https://pybind11.readthedocs.io/en/stable/

安装:

pip3 install pybind11

示例:

https://github.com/pybind/cmake_example

手动添加wrapper太麻烦。目前有一些开源项目,专门用来针对已有的C++代码来自动生成pybind11绑定代码:

  • binder
  • AutoWIG
  • robotpy-build

示例:

class CivilNet {
    public:
        CivilNet(const std::string &name) : name_(name) { }
        void setName(const std::string &name) { name_ = name; }
        const std::string &getName() const { return name_; }
    private:
        std::string name_;
};

PYBIND11_MODULE(my_bind_module, m) {
    pybind11::class_<CivilNet>(m, "CivilNet")
        .def(pybind11::init<const std::string &>())
        .def("setName", &CivilNet::setName)
        .def("getName", &CivilNet::getName);
}

参考:

https://github.com/tensorflow/community/blob/master/rfcs/20190208-pybind11.md

pybind11 vs SWIG

https://zhuanlan.zhihu.com/p/52619334

使用pybind11将C++代码编译为python模块

https://zhuanlan.zhihu.com/p/192974017

pybind11的最佳实践

https://zhuanlan.zhihu.com/p/666269440

PyBind11简明教程

nanobind

nanobind是pybind11的作者Wenzel Jakob的新作。

nanobind只面向现代C++17及以上,让代码适配工具,不再兼容老旧代码。显著降低构建与运行开销,并缩减发布体积。

CPython提出了Stable ABI(也叫 ABI3)标准,如果只使用该标准定义的有限API,就承诺同一大版本系列(3.x)内,头文件、结构体布局、函数签名都不会变,因此3.12编译出的.abi3.so可以在3.13、3.14… 上直接加载,无需重新编译。

nanobind也遵循了ABI3标准。

python调用GTK函数的一般规则

众所周知,GTK库是用C语言编写的,其相关的文档提供的也是C函数的接口,python接口的文档相对较少,获得也不太容易。因此有必要掌握一下这方面基本的命名规则。(这里只讲方法,对深层次的调用原理不做探究。)

1)类初始化函数

C:GtkWidget * gtk_button_new (void);

python:button = Gtk.Button()

这里除了把C函数式的写法,替换成python的类的写法之外,并无其他差异。

2)普通类成员函数

C:void gtk_container_add (GtkContainer *container, GtkWidget *widget);

python:button.add(image)

可以看出,C函数的第一个表示self类指针的参数被省略掉了。

3)回调函数

这里以按钮的click事件回调为例:

C:void user_function (GtkButton *button, gpointer user_data)

python:

button.connect("clicked", self.playToggled)

def playToggled(self, w):

这里的情况要复杂的多。首先在事件回调注册的时候,由于我们并没有给user_data赋值,因此照理说playToggled函数,只有button这一个参数。但实际传递给playToggled函数的有两个参数,self是一个用于占位的参数,w对应button,没有东西对应user_data。

4)用于输出的参数

C:void gst_message_parse_error (GstMessage *message, GError **gerror, gchar **debug);

python:err, debug = message.parse_error()

这个例子中的gerror和debug都是用于输出的参数。如果只想得到其一,还可用以下方法:

debug = message.parse_error()[2]

5)枚举类型

C:

enum GstSeekFlags
{
  GST_SEEK_FLAG_FLUSH,
  ...
}

python:Gst.SeekFlags.FLUSH

6)宏常量

C:#define GST_CLOCK_TIME_NONE ((GstClockTime) -1)

python:Gst.CLOCK_TIME_NONE

7)类型转换

大多数情况下,类型转换自动完成,并无什么问题。这里只讨论特殊的情况。

C:

gst_element_seek (pipeline, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
                         GST_SEEK_TYPE_SET, time_nanoseconds,
                         GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE))

python:

self.player.seek(1.0, Gst.Format.TIME, Gst.SeekFlags.FLUSH, Gst.SeekType.SET,\
                 time_nanoseconds, Gst.SeekType.NONE, Gst.CLOCK_TIME_NONE)

这里首先按照一般的方法,将C代码转化成python代码。但是运行之后,产生如下错误:

OverflowError: long too big to convert

究其原因,gst_element_seek的最后一个参数是uint64类型的。但python原生并不支持该类型,而是将之转换成int类型(实际上是int64类型),这样的话,GST_CLOCK_TIME_NONE的值显然超出了int64所能表示的范围。

解决的办法是使用ctypes库,将

Gst.CLOCK_TIME_NONE

改为

c_long(Gst.CLOCK_TIME_NONE).value

Fork me on GitHub