精华内容
下载资源
问答
  • 这篇文章主要介绍了在Python程序中实现分布式进程的教程,多进程编程十分有用,示例代码基于Python2.x版本,需要的朋友可以参考下 Thread和Process,应当优选Process,因为Process更稳定,而且,Process可以...

    @本文来源于公众号:csdn2299,喜欢可以关注公众号 程序员学府
    这篇文章主要介绍了在Python程序中实现分布式进程的教程,在多进程编程中十分有用,示例代码基于Python2.x版本,需要的朋友可以参考下
    在Thread和Process中,应当优选Process,因为Process更稳定,而且,Process可以分布到多台机器上,而Thread最多只能分布到同一台机器的多个CPU上。

    Python的multiprocessing模块不但支持多进程,其中managers子模块还支持把多进程分布到多台机器上。一个服务进程可以作为调度者,将任务分布到其他多个进程中,依靠网络通信。由于managers模块封装很好,不必了解网络通信的细节,就可以很容易地编写分布式多进程程序。

    举个例子:如果我们已经有一个通过Queue通信的多进程程序在同一台机器上运行,现在,由于处理任务的进程任务繁重,希望把发送任务的进程和处理任务的进程分布到两台机器上。怎么用分布式进程实现?

    原有的Queue可以继续使用,但是,通过managers模块把Queue通过网络暴露出去,就可以让其他机器的进程访问Queue了。

    我们先看服务进程,服务进程负责启动Queue,把Queue注册到网络上,然后往Queue里面写入任务:

    # taskmanager.py
     
    import random, time, Queue
    from multiprocessing.managers import BaseManager
     
    # 发送任务的队列:
    task_queue = Queue.Queue()
    # 接收结果的队列:
    result_queue = Queue.Queue()
     
    # 从BaseManager继承的QueueManager:
    class QueueManager(BaseManager):
      pass
     
    # 把两个Queue都注册到网络上, callable参数关联了Queue对象:
    QueueManager.register('get_task_queue', callable=lambda: task_queue)
    QueueManager.register('get_result_queue', callable=lambda: result_queue)
    # 绑定端口5000, 设置验证码'abc':
    manager = QueueManager(address=('', 5000), authkey='abc')
    # 启动Queue:
    manager.start()
    # 获得通过网络访问的Queue对象:
    task = manager.get_task_queue()
    result = manager.get_result_queue()
    # 放几个任务进去:
    for i in range(10):
      n = random.randint(0, 10000)
      print('Put task %d...' % n)
      task.put(n)
    # 从result队列读取结果:
    print('Try get results...')
    for i in range(10):
      r = result.get(timeout=10)
      print('Result: %s' % r)
    # 关闭:
    manager.shutdown()
    

    请注意,当我们在一台机器上写多进程程序时,创建的Queue可以直接拿来用,但是,在分布式多进程环境下,添加任务到Queue不可以直接对原始的task_queue进行操作,那样就绕过了QueueManager的封装,必须通过manager.get_task_queue()获得的Queue接口添加。

    然后,在另一台机器上启动任务进程(本机上启动也可以):

    # taskworker.py
     
    import time, sys, Queue
    from multiprocessing.managers import BaseManager
     
    # 创建类似的QueueManager:
    class QueueManager(BaseManager):
      pass
     
    # 由于这个QueueManager只从网络上获取Queue,所以注册时只提供名字:
    QueueManager.register('get_task_queue')
    QueueManager.register('get_result_queue')
     
    # 连接到服务器,也就是运行taskmanager.py的机器:
    server_addr = '127.0.0.1'
    print('Connect to server %s...' % server_addr)
    # 端口和验证码注意保持与taskmanager.py设置的完全一致:
    m = QueueManager(address=(server_addr, 5000), authkey='abc')
    # 从网络连接:
    m.connect()
    # 获取Queue的对象:
    task = m.get_task_queue()
    result = m.get_result_queue()
    # 从task队列取任务,并把结果写入result队列:
    for i in range(10):
      try:
        n = task.get(timeout=1)
        print('run task %d * %d...' % (n, n))
        r = '%d * %d = %d' % (n, n, n*n)
        time.sleep(1)
        result.put(r)
      except Queue.Empty:
        print('task queue is empty.')
    # 处理结束:
    print('worker exit.')
    

    任务进程要通过网络连接到服务进程,所以要指定服务进程的IP。

    现在,可以试试分布式进程的工作效果了。先启动taskmanager.py服务进程:

    $ python taskmanager.py 
    Put task 3411...
    Put task 1605...
    Put task 1398...
    Put task 4729...
    Put task 5300...
    Put task 7471...
    Put task 68...
    Put task 4219...
    Put task 339...
    Put task 7866...
    Try get results...
    

    taskmanager进程发送完任务后,开始等待result队列的结果。现在启动taskworker.py进程:

    $ python taskworker.py 127.0.0.1
    Connect to server 127.0.0.1...
    run task 3411 * 3411...
    run task 1605 * 1605...
    run task 1398 * 1398...
    run task 4729 * 4729...
    run task 5300 * 5300...
    run task 7471 * 7471...
    run task 68 * 68...
    run task 4219 * 4219...
    run task 339 * 339...
    run task 7866 * 7866...
    worker exit.
    

    taskworker进程结束,在taskmanager进程中会继续打印出结果:

    Result: 3411 * 3411 = 11634921
    Result: 1605 * 1605 = 2576025
    Result: 1398 * 1398 = 1954404
    Result: 4729 * 4729 = 22363441
    Result: 5300 * 5300 = 28090000
    Result: 7471 * 7471 = 55815841
    Result: 68 * 68 = 4624
    Result: 4219 * 4219 = 17799961
    Result: 339 * 339 = 114921
    Result: 7866 * 7866 = 61873956
    

    这个简单的Manager/Worker模型有什么用?其实这就是一个简单但真正的分布式计算,把代码稍加改造,启动多个worker,就可以把任务分布到几台甚至几十台机器上,比如把计算n*n的代码换成发送邮件,就实现了邮件队列的异步发送。

    Queue对象存储在哪?注意到taskworker.py中根本没有创建Queue的代码,所以,Queue对象存储在taskmanager.py进程中:
    在这里插入图片描述
    而Queue之所以能通过网络访问,就是通过QueueManager实现的。由于QueueManager管理的不止一个Queue,所以,要给每个Queue的网络调用接口起个名字,比如get_task_queue。

    authkey有什么用?这是为了保证两台机器正常通信,不被其他机器恶意干扰。如果taskworker.py的authkey和taskmanager.py的authkey不一致,肯定连接不上。
    小结

    Python的分布式进程接口简单,封装良好,适合需要把繁重任务分布到多台机器的环境下。

    注意Queue的作用是用来传递任务和接收结果,每个任务的描述数据量要尽量小。比如发送一个处理日志文件的任务,就不要发送几百兆的日志文件本身,而是发送日志文件存放的完整路径,由Worker进程再去共享的磁盘上读取文件。

    非常感谢你的阅读
    大学的时候选择了自学python,工作了发现吃了计算机基础不好的亏,学历不行这是没办法的事,只能后天弥补,于是在编码之外开启了自己的逆袭之路,不断的学习python核心知识,深入的研习计算机基础知识,整理好了,我放在我们的微信公众号《程序员学府》,如果你也不甘平庸,那就与我一起在编码之外,不断成长吧!

    其实这里不仅有技术,更有那些技术之外的东西,比如,如何做一个精致的程序员,而不是“屌丝”,程序员本身就是高贵的一种存在啊,难道不是吗?[点击加入]
    想做你自己想成为高尚人,加油!

    展开全文
  • 如何C++调用python程序

    千次阅读 2019-11-08 08:48:07
    Embedding Python in Another Application 将Python嵌入另一个应用程序中1.1. Very High Level Embedding 高层嵌入1.2. Beyond Very High Level Embedding: An overview 超越高级嵌入:概述1.3. Pure Embedding 纯...

    1. Embedding Python in Another Application 将Python嵌入另一个应用程序中

    The previous chapters discussed how to extend Python, that is, how to extend the functionality of Python by attaching a library of C functions to it. It is also possible to do it the other way around: enrich your C/C++ application by embedding Python in it. Embedding provides your application with the ability to implement some of the functionality of your application in Python rather than C or C++. This can be used for many purposes; one example would be to allow users to tailor the application to their needs by writing some scripts in Python. You can also use it yourself if some of the functionality can be written in Python more easily.

    前面的章节讨论了如何扩展Python,即如何通过将C函数库附加到Python来扩展Python的功能。也可以通过其他方式做到这一点:通过将Python嵌入到C / C ++应用程序中来丰富它。嵌入为您的应用程序提供了使用Python而非C或C ++实现应用程序某些功能的能力。这可以用于许多目的。一个示例是允许用户通过使用Python编写一些脚本来根据自己的需求定制应用程序。如果某些功能可以更轻松地用Python编写,那么您也可以自己使用它。

    Embedding Python is similar to extending it, but not quite. The difference is that when you extend Python, the main program of the application is still the Python interpreter, while if you embed Python, the main program may have nothing to do with Python — instead, some parts of the application occasionally call the Python interpreter to run some Python code.

    嵌入Python与扩展Python类似,但不完全相同。区别在于,当您扩展Python时,应用程序的主程序仍然是Python解释器,而如果您嵌入Python,则主程序可能与Python无关—相反,应用程序的某些部分有时会调用Python解释器运行一些Python代码。

    So if you are embedding Python, you are providing your own main program. One of the things this main program has to do is initialize the Python interpreter. At the very least, you have to call the function Py_Initialize(). There are optional calls to pass command line arguments to Python. Then later you can call the interpreter from any part of the application.

    因此,如果您要嵌入Python,那么您将提供自己的主程序。这个主程序要做的一件事就是初始化Python解释器。至少,您必须调用函数Py_Initialize()。有一些可选的调用,可将命令行参数传递给Python。然后,您可以从应用程序的任何部分调用解释器。

    There are several different ways to call the interpreter: you can pass a string containing Python statements to PyRun_SimpleString(), or you can pass a stdio file pointer and a file name (for identification in error messages only) to PyRun_SimpleFile(). You can also call the lower-level operations described in the previous chapters to construct and use Python objects.

    有几种不同的调用解释器的方式:可以将包含Python语句的字符串传递给PyRun_SimpleString(),或者可以将stdio文件指针和文件名(仅用于错误消息中的标识)传递给PyRun_SimpleFile()。您还可以调用前面各章中描述的较低级别的操作来构造和使用Python对象。

    参见
    Python/C API 参考手册
    The details of Python’s C interface are given in this manual. A great deal of necessary information can be found here.

    1.1. Very High Level Embedding 高层嵌入

    The simplest form of embedding Python is the use of the very high level interface. This interface is intended to execute a Python script without needing to interact with the application directly. This can for example be used to perform some operation on a file.

    嵌入Python的最简单形式是使用非常高级的接口。该接口旨在执行Python脚本,而无需直接与应用程序进行交互。例如,这可用于对文件执行某些操作。

    #define PY_SSIZE_T_CLEAN
    #include <Python.h>
    
    int
    main(int argc, char *argv[])
    {
        wchar_t *program = Py_DecodeLocale(argv[0], NULL);
        if (program == NULL) {
            fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
            exit(1);
        }
        Py_SetProgramName(program);  /* optional but recommended */
        Py_Initialize();
        PyRun_SimpleString("from time import time,ctime\n"
                           "print('Today is', ctime(time()))\n");
        if (Py_FinalizeEx() < 0) {
            exit(120);
        }
        PyMem_RawFree(program);
        return 0;
    }
    

    The Py_SetProgramName() function should be called before Py_Initialize() to inform the interpreter about paths to Python run-time libraries. Next, the Python interpreter is initialized with Py_Initialize(), followed by the execution of a hard-coded Python script that prints the date and time. Afterwards, the Py_FinalizeEx() call shuts the interpreter down, followed by the end of the program. In a real program, you may want to get the Python script from another source, perhaps a text-editor routine, a file, or a database. Getting the Python code from a file can better be done by using the PyRun_SimpleFile() function, which saves you the trouble of allocating memory space and loading the file contents.

    Py_SetProgramName()Py_Initialize()通知解释器有关Python运行时库的路径之前,应先调用该函数 。接下来,使用初始化Python解释器 Py_Initialize(),然后执行打印日期和时间的硬编码Python脚本。之后,该Py_FinalizeEx()调用将关闭解释器,然后结束程序。在实际程序中,您可能希望从其他来源(可能是文本编辑器例程,文件或数据库)获取Python脚本。使用该PyRun_SimpleFile()函数可以更好地从文件中获取Python代码,从而避免了分配内存空间和加载文件内容的麻烦。

    1.2. Beyond Very High Level Embedding: An overview 超越高级嵌入:概述

    The high level interface gives you the ability to execute arbitrary pieces of Python code from your application, but exchanging data values is quite cumbersome to say the least. If you want that, you should use lower level calls. At the cost of having to write more C code, you can achieve almost anything.

    高级接口使您能够从应用程序中执行任意段Python代码,但是至少可以说,交换数据值非常麻烦。如果需要,应该使用较低级别的调用。以编写更多的C代码为代价,您几乎可以实现任何目标。

    It should be noted that extending Python and embedding Python is quite the same activity, despite the different intent. Most topics discussed in the previous chapters are still valid. To show this, consider what the extension code from Python to C really does:

    应该注意的是,尽管意图不同,但扩展Python和嵌入Python是完全相同的活动。前几章讨论的大多数主题仍然有效。为了说明这一点,请考虑一下从Python到C的扩展代码的实际作用:

    1. Convert data values from Python to C,
      将数据值从Python转换为C,

    2. Perform a function call to a C routine using the converted values, and
      使用转换后的值对C例程执行函数调用,然后

    3. Convert the data values from the call from C to Python.
      将调用中的数据值从C转换为Python。

    When embedding Python, the interface code does:
    嵌入Python时,接口代码执行以下操作:

    1. Convert data values from C to Python,
      将数据值从C转换为Python,

    2. Perform a function call to a Python interface routine using the converted values, and
      使用转换后的值执行对Python接口例程的函数调用,以及

    3. Convert the data values from the call from Python to C.
      将调用中的数据值从Python转换为C。

    As you can see, the data conversion steps are simply swapped to accommodate the different direction of the cross-language transfer. The only difference is the routine that you call between both data conversions. When extending, you call a C routine, when embedding, you call a Python routine.

    如您所见,只需转换数据转换步骤即可适应跨语言传输的不同方向。唯一的区别是两次数据转换之间调用的例程。扩展时,您调用C例程,嵌入时,您调用Python例程。

    This chapter will not discuss how to convert data from Python to C and vice versa. Also, proper use of references and dealing with errors is assumed to be understood. Since these aspects do not differ from extending the interpreter, you can refer to earlier chapters for the required information.

    1.3. Pure Embedding 纯嵌入

    The first program aims to execute a function in a Python script. Like in the section about the very high level interface, the Python interpreter does not directly interact with the application (but that will change in the next section).

    第一个程序旨在在Python脚本中执行功能。就像在有关高级界面的部分中一样,Python解释器不会直接与应用程序进行交互(但是在下一部分中会有所变化)。

    The code to run a function defined in a Python script is:

    运行Python脚本中定义的函数的代码为:

    #define PY_SSIZE_T_CLEAN
    #include <Python.h>
    
    int
    main(int argc, char *argv[])
    {
        PyObject *pName, *pModule, *pFunc;
        PyObject *pArgs, *pValue;
        int i;
    
        if (argc < 3) {
            fprintf(stderr,"Usage: call pythonfile funcname [args]\n");
            return 1;
        }
    
        Py_Initialize();
        pName = PyUnicode_DecodeFSDefault(argv[1]);
        /* Error checking of pName left out */
    
        pModule = PyImport_Import(pName);
        Py_DECREF(pName);
    
        if (pModule != NULL) {
            pFunc = PyObject_GetAttrString(pModule, argv[2]);
            /* pFunc is a new reference */
    
            if (pFunc && PyCallable_Check(pFunc)) {
                pArgs = PyTuple_New(argc - 3);
                for (i = 0; i < argc - 3; ++i) {
                    pValue = PyLong_FromLong(atoi(argv[i + 3]));
                    if (!pValue) {
                        Py_DECREF(pArgs);
                        Py_DECREF(pModule);
                        fprintf(stderr, "Cannot convert argument\n");
                        return 1;
                    }
                    /* pValue reference stolen here: */
                    PyTuple_SetItem(pArgs, i, pValue);
                }
                pValue = PyObject_CallObject(pFunc, pArgs);
                Py_DECREF(pArgs);
                if (pValue != NULL) {
                    printf("Result of call: %ld\n", PyLong_AsLong(pValue));
                    Py_DECREF(pValue);
                }
                else {
                    Py_DECREF(pFunc);
                    Py_DECREF(pModule);
                    PyErr_Print();
                    fprintf(stderr,"Call failed\n");
                    return 1;
                }
            }
            else {
                if (PyErr_Occurred())
                    PyErr_Print();
                fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]);
            }
            Py_XDECREF(pFunc);
            Py_DECREF(pModule);
        }
        else {
            PyErr_Print();
            fprintf(stderr, "Failed to load \"%s\"\n", argv[1]);
            return 1;
        }
        if (Py_FinalizeEx() < 0) {
            return 120;
        }
        return 0;
    }
    

    This code loads a Python script using argv[1], and calls the function named in argv[2]. Its integer arguments are the other values of the argv array. If you compile and link this program (let’s call the finished executable call), and use it to execute a Python script, such as:

    此代码使用加载Python脚本argv[1],并调用中命名的函数argv[2]。它的整数参数是argv 数组的其他值。如果编译并链接该程序(让我们调用完成的可执行调用),并使用它执行Python脚本,例如:

    def multiply(a,b):
        print("Will compute", a, "times", b)
        c = 0
        for i in range(0, a):
            c = c + b
        return c
    

    then the result should be:

    那么结果应该是:

    $ call multiply multiply 3 2
    Will compute 3 times 2
    Result of call: 6
    

    Although the program is quite large for its functionality, most of the code is for data conversion between Python and C, and for error reporting. The interesting part with respect to embedding Python starts with

    尽管该程序的功能非常庞大,但大多数代码都是用于Python和C之间的数据转换以及错误报告。关于嵌入Python的有趣部分始于

    Py_Initialize();
    pName = PyUnicode_DecodeFSDefault(argv[1]);
    /* Error checking of pName left out */
    pModule = PyImport_Import(pName);
    

    After initializing the interpreter, the script is loaded using PyImport_Import(). This routine needs a Python string as its argument, which is constructed using the PyUnicode_FromString() data conversion routine.

    初始化解释器后,使用加载脚本 PyImport_Import()。该例程需要一个Python字符串作为其参数,该字符串是使用PyUnicode_FromString()数据转换例程构造的。

    pFunc = PyObject_GetAttrString(pModule, argv[2]);
    /* pFunc is a new reference */
    
    if (pFunc && PyCallable_Check(pFunc)) {
        ...
    }
    Py_XDECREF(pFunc);
    

    Once the script is loaded, the name we’re looking for is retrieved using PyObject_GetAttrString(). If the name exists, and the object returned is callable, you can safely assume that it is a function. The program then proceeds by constructing a tuple of arguments as normal. The call to the Python function is then made with:

    加载脚本后,将使用查找所需的名称 PyObject_GetAttrString()。如果名称存在,并且返回的对象是可调用的,则可以安全地假定它是一个函数。然后,程序通过正常构造参数元组继续进行。然后使用以下命令调用Python函数:

    pValue = PyObject_CallObject(pFunc, pArgs);
    

    Upon return of the function, pValue is either NULL or it contains a reference to the return value of the function. Be sure to release the reference after examining the value.

    函数返回时,pValueNULL或包含对函数返回值的引用。检查值之后,请确保释放参考。

    1.4. Extending Embedded Python

    Until now, the embedded Python interpreter had no access to functionality from the application itself. The Python API allows this by extending the embedded interpreter. That is, the embedded interpreter gets extended with routines provided by the application. While it sounds complex, it is not so bad. Simply forget for a while that the application starts the Python interpreter. Instead, consider the application to be a set of subroutines, and write some glue code that gives Python access to those routines, just like you would write a normal Python extension. For example:

    到目前为止,嵌入式Python解释器无法从应用程序本身访问功能。Python API通过扩展嵌入式解释器来实现这一点。也就是说,嵌入式解释器将使用应用程序提供的例程进行扩展。虽然听起来很复杂,但还不错。只需暂时忘记应用程序启动Python解释器。相反,应将应用程序视为一组子例程,并编写一些粘合代码以使Python可以访问这些例程,就像编写普通的Python扩展一样。例如:

    static int numargs=0;
    
    /* Return the number of arguments of the application command line */
    static PyObject*
    emb_numargs(PyObject *self, PyObject *args)
    {
        if(!PyArg_ParseTuple(args, ":numargs"))
            return NULL;
        return PyLong_FromLong(numargs);
    }
    
    static PyMethodDef EmbMethods[] = {
        {"numargs", emb_numargs, METH_VARARGS,
         "Return the number of arguments received by the process."},
        {NULL, NULL, 0, NULL}
    };
    
    static PyModuleDef EmbModule = {
        PyModuleDef_HEAD_INIT, "emb", NULL, -1, EmbMethods,
        NULL, NULL, NULL, NULL
    };
    
    static PyObject*
    PyInit_emb(void)
    {
        return PyModule_Create(&EmbModule);
    }
    

    Insert the above code just above the main() function. Also, insert the following two statements before the call to Py_Initialize():

    在main()函数上方插入上面的代码。另外,在对的调用之前插入以下两个语句Py_Initialize()

    numargs = argc;
    PyImport_AppendInittab("emb", &PyInit_emb);
    

    These two lines initialize the numargs variable, and make the emb.numargs() function accessible to the embedded Python interpreter. With these extensions, the Python script can do things like

    这两行初始化numargs变量,并使该 emb.numargs()函数可被嵌入式Python解释器访问。通过这些扩展,Python脚本可以执行以下操作

    import emb
    print("Number of arguments", emb.numargs())
    

    In a real application, the methods will expose an API of the application to Python.

    在实际的应用程序中,这些方法会将应用程序的API公开给Python。

    1.5. Embedding Python in C++ 在C ++中嵌入Python

    It is also possible to embed Python in a C++ program; precisely how this is done will depend on the details of the C++ system used; in general you will need to write the main program in C++, and use the C++ compiler to compile and link your program. There is no need to recompile Python itself using C++.

    也可以将Python嵌入C ++程序中。确切地讲,这将取决于所使用的C ++系统的细节。通常,您将需要用C ++编写主程序,并使用C ++编译器来编译和链接程序。无需使用C ++重新编译Python本身。

    1.6. Compiling and Linking under Unix-like systems 编译和在类Unix系统链接

    It is not necessarily trivial to find the right flags to pass to your compiler (and linker) in order to embed the Python interpreter into your application, particularly because Python needs to load library modules implemented as C dynamic extensions (.so files) linked against it.

    找到正确的标志传递给编译器(和链接器)以将Python解释器嵌入到您的应用程序中并不一定很简单,尤其是因为Python需要加载实现为.so与其链接的C动态扩展(文件)的库模块。

    To find out the required compiler and linker flags, you can execute the pythonX.Y-config script which is generated as part of the installation process (a python3-config script may also be available). This script has several options, of which the following will be directly useful to you:

    要找出所需的编译器和链接器标志,您可以执行 在安装过程中生成的脚本(也可以使用脚本)。该脚本有多个选项,其中的以下选项对您直接有用:pythonX.Y-configpython3-config

    • pythonX.Y-config --cflags will give you the recommended flags when compiling:
      pythonX.Y-config --cflags 编译时会给您推荐的标志:
    $ /opt/bin/python3.4-config --cflags
    -I/opt/include/python3.4m -I/opt/include/python3.4m -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes
    
    • pythonX.Y-config --ldflags will give you the recommended flags when linking:
      pythonX.Y-config --ldflags 链接时会为您提供推荐的标志:
    $ /opt/bin/python3.4-config --ldflags
    -L/opt/lib/python3.4/config-3.4m -lpthread -ldl -lutil -lm -lpython3.4m -Xlinker -export-dynamic
    

    注解 To avoid confusion between several Python installations (and especially between the system Python and your own compiled Python), it is recommended that you use the absolute path to pythonX.Y-config, as in the above example.

    注解 为了避免一些Python的设备之间的混淆(尤其是系统Python和自己编译的Python之间),因此建议您使用绝对路径,如上面的例子。pythonX.Y-config

    If this procedure doesn’t work for you (it is not guaranteed to work for all Unix-like platforms; however, we welcome bug reports) you will have to read your system’s documentation about dynamic linking and/or examine Python’s Makefile (use sysconfig.get_makefile_filename() to find its location) and compilation options. In this case, the sysconfig module is a useful tool to programmatically extract the configuration values that you will want to combine together. For example:

    如果此程序对您不起作用(不能保证在所有类Unix平台上都有效;但是,我们欢迎提供错误报告),则您必须阅读系统文档中有关动态链接和/或检查Python的文档Makefile(用于sysconfig.get_makefile_filename() 查找其位置)和编译选项。在这种情况下,该sysconfig模块是有用的工具,可用于以编程方式提取要组合在一起的配置值。例如:

    >>> import sysconfig
    >>> sysconfig.get_config_var('LIBS')
    '-lpthread -ldl  -lutil'
    >>> sysconfig.get_config_var('LINKFORSHARED')
    '-Xlinker -export-dynamic'
    

    参考文章:Embedding Python in Another Application

    展开全文
  • Python数据

    千次阅读 2017-08-19 18:23:33
    最近很多人问怎么抓网页数据,据我所知,常见的编程语言(C++,java,python)都可以实现抓网页数据,甚至很多统计\计算的语言(R,Matlab)都有可以实现和网站交互的包。本人试过用java,python,R抓网页,感觉语法各有差异...
    前言:
    数据科学越来越火了,网页是数据很大的一个来源。最近很多人问怎么抓网页数据,据我所知,常见的编程语言(C++,java,python)都可以实现抓网页数据,甚至很多统计\计算的语言(R,Matlab)都有可以实现和网站交互的包。本人试过用java,python,R抓网页,感觉语法各有差异,逻辑上是一样的。我准备用python来大概讲讲抓网页是什么概念,具体的内容要自己看手册或者google别人的博客,这里算是抛砖引玉了。水平有限,出现错误或者有更好的办法,欢迎讨论。
    . visit 1point3acres.com for more.
    步骤一:熟悉Python的基本语法。
    已经熟悉Python的直接跳到步骤二。
    Python是门比较容易入门的编程语言,如何上手视编程基础而定。
    (1) 如果有一定编程的基础,建议看google's python class,链接https://developers.google.com/edu/python/?hl=zh-CN&csw=1
    这个是一个为期两天的短期培训课程(当然,是两个全天),大概是七个视频,每个视频之后给编程作业,每个作业一个小时之内可以完成。这是我学习python的第二门课(第一门是codecademy的python,很早之前看的,很多内容都记不得了),当时每天看视频+编程作业一个多小时,六天弄完,效果还不错,用python写基本的程序没有问题。
    (2) 如果是没有任何编程基础,建议看coursera上Rice University开的An Introduction to Interactive Programming in Python。这门课我没有跟过,但是看coursetalk的评论反映非常好,地里也有同学评论(点这里),课程链接:https://www.coursera.org/course/interactivepython。Udacity上的CS101也是不错的选择,地里有相关的讨论帖(点这里),而且这门课就叫做build a search engine,会专门讲一些和网络相关的module。其他学习资源还有code school和codecademy,这些资源也是挺不错的,但是编程量太少,初学者还是系统的跟课、多练练手来打好基础吧。
    当然,每个人的偏好不同,我推荐的不一定适合你。可以先看看这个帖子【长期加分贴】介绍你上过的公开课里面其他人是怎么说的,或者上coursetalk.org看看课程评论,再决定吧。

    . visit 1point3acres.com for more.
    步骤二:学会如何与网站建立链接,得到网页数据。
    写脚本与网站进行交互,要熟悉python和网页相关的几个module(urllib,urllib2,httplib)中的一个,知道一个即可,其他的都类似的。这三个是python提供的和网页交互的基本module,还有其他的一些,比如:mechanize和scrappy,我没有用过,可能有更好的性能,欢迎了解的来补充。基本的网页抓取,前面的三个module足矣。
    下面的代码演示如何用urllib2与google scholar进行交互,获得网页信息。. From 1point 3acres bbs
    1. # 导入模块 urllib2. more info on 1point3acres.com
    2. import urllib2. From 1point 3acres bbs

    3. # 随便查询一篇文章,比如On random graph。对每一个查询google 
    4. # scholar都有一个url,这个url形成的规则是要自己分析的。. 1point 3acres 璁哄潧
    5. query = 'On+random+graph'. From 1point 3acres bbs
    6. url = 'http://scholar.google.com/scholar?hl=en&q=' + query + '&btnG=&as_sdt=1%2C5&as_sdtp='
    7. # 设置头文件。抓取有些的网页不需要专门设置头文件,但是这里如果不设置的话,
    8. # google会认为是机器人不允许访问。另外访问有些网站还有设置Cookie,这个会相对复杂一些,
    9. # 这里暂时不提。关于怎么知道头文件该怎么写,一些插件可以看到你用的浏览器和网站交互的
    10. # 头文件(这种工具很多浏览器是自带的),我用的是firefox的firebug插件。
    11. header = {'Host': 'scholar.google.com',
    12. 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; rv:26.0) Gecko/20100101 Firefox/26.0',
    13. 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    14. 'Accept-Encoding': 'gzip, deflate',
    15. 'Connection': 'keep-alive'}
    16. # 建立连接请求,这时google的服务器返回页面信息给con这个变量,con是一个对象
    17. req = urllib2.Request(url, headers = header) .鐣欏璁哄潧-涓€浜�-涓夊垎鍦�
    18. con = urllib2.urlopen( req )
    19. # 对con这个对象调用read()方法,返回的是html页面,也就是有html标签的纯文本
    20. doc = con.read()
    21. # 关闭连接。就像读完文件要关闭文件一样,如果不关闭有时可以、但有时会有问题,
    22. # 所以作为一个守法的好公民,还是关闭连接好了。
    23. con.close()
    复制代码
    以上的代码就把在google scholar上查询On Random Graph的结果返回到doc这个变量中了,这个和你打开google scholar搜索On Random Graph,然后将网页右键保存的效果是一样的。

    步骤三、解析网页 鏉ユ簮涓€浜�.涓夊垎鍦拌鍧�. 
    上面的步骤得到了网页的信息,但是包括了html标签,你要把这些标签去掉,然后从html文本中整理出有用的信息,
    你需要解析这个网页。
    解析网页的方法:
    (1) 正则表达式。正则表达式很有用,熟悉它节省很多的时间,有时候清洗数据不用写脚本或者在数据库上查询,直接在notepad++上用正则表达式组合使用就行了。如何学习正则表达式建议看:正则表达式30分钟入门教程,链接:http://deerchao.net/tutorials/regex/regex.htm.鐣欏璁哄潧-涓€浜�-涓夊垎鍦�
    (2) BeautifulSoup模块。BeautifulSoup是一个很强大的模块,能把html文件解析成一个对象,这个对象是一棵树。我们都知道html文件是树状的,比如 body -> table -> tbody -> tr,对于tbody这个节点,有很多个tr的子节点。BeautifulSoup可以很方便的取到特定的节点,对单个节点也可以取它的sibling node。网上有很多相关的说明,这里不细说,只演示简单的代码:
    (3) 上面两种方法结合使用。
    1. # 导入BeautifulSoup模块和re模块,re是python中正则表达式的模块. 涓€浜�-涓夊垎-鍦帮紝鐙鍙戝竷
    2. import BeautifulSoup
    3. import re
    4. # 生成一个soup对象,doc就是步骤二中提到的
    5. soup = BeautifulSoup.BeautifulSoup(doc)
    6. # 抓取论文标题,作者,简短描述,引用次数,版本数,引用它的文章列表的超链接
    7. # 这里还用了一些正则表达式,不熟悉的先无知它好了。至于'class' : 'gs_rt'中
    8. # 'gs_rt'是怎么来的,这个是分析html文件肉眼看出来的。上面提到的firebug插件
    9. # 让这个变的很简单,只要一点网页,就可以知道对应的html 标签的位置和属性,
    10. # 相当好用。
    11. paper_name = soup.html.body.find('h3', {'class' : 'gs_rt'}).text
    12. paper_name = re.sub(r'\[.*\]', '', paper_name) # eliminate '[]' tags like '[PDF]'
    13. paper_author = soup.html.body.find('div', {'class' : 'gs_a'}).text
    14. paper_desc = soup.html.body.find('div', {'class' : 'gs_rs'}).text
    15. temp_str = soup.html.body.find('div', {'class' : 'gs_fl'}).text
    16. temp_re = re.match(r'[A-Za-z\s]+(\d*)[A-Za-z\s]+(\d*)', temp_str). 鐗涗汉浜戦泦,涓€浜╀笁鍒嗗湴
    17. citeTimes = temp_re.group(1)
    18. versionNum = temp_re.group(2)
    19. if citeTimes == '':
    20.   citeTimes = '0'
    21. if versionNum == '':. 1point3acres.com/bbs
    22.   versionNum = '0'
    23. citedPaper_href = soup.html.body.find('div', {'class' : 'gs_fl'}).a.attrs[0][1]
    复制代码

    这些都是我在一个分析citation network的项目的代码。顺便一提,我从google scholar上抓取paper的信息以及引用列表的信息,访问了大概1900次左右的时候给google block了,导致这个片区的ip一时无法登陆google scholar。

    步骤四:存取数据
    好不容易抓了数据,现在只是存储在内存中,必须保存起来才能利用。
    (1) 最简单的方法之把数据写进txt文件中,Python中可以用如下代码实现:
    . visit 1point3acres.com for more.
    1. # 打开文件webdata.txt,生成对象file,这个文件可以是不存在的,参数a表示往里面添加。
    2. # 还有别的参数,比如'r'只能读但不能写入,'w'可以写入但是会删除原来的记录等等
    3. file = open('webdata.txt','a'). Waral 鍗氬鏈夋洿澶氭枃绔�,
    4. line = paper_name + '#' + paper_author + '#' + paper_desc + '#' + citeTimes + '\n'
    5. # 对象file的write方法将字符串line写入file中
    6. file = file.write(line)
    7. # 再一次的,做个随手关闭文件的好青年
    8. file.close()
    复制代码
    这样,就把从网页上抓到并且解析了的数据存储到本地了,是不是很简单?. From 1point 3acres bbs
    (2) 当然,你也可以不写入txt文件中,而是直接连接数据库,python中的MySQLdb模块可以实现和MySQL数据库的交互,把数据直接倒到数据库里面,与MySQL数据库建立链接的逻辑和与网站服务器建立链接的逻辑差不多。如果之前有学习过数据库,学习用MySQLdb模块实现和数据库的交互是很简单的;如果没有,则要借助在coursera\stanford openedx平台上都有开设的Introduction to Database来系统学习,w3school用来参考或者当成手册。
    Python能够链接数据库的前提是数据库是开着的,我用的是 win7 + MySQL5.5,数据库在本地。
    1. %可以用cmd开启数据库,启动命令是:
    2. net start mysql55
    3. %关闭命令是:
    4. net stop mysql55
    复制代码
    使用MySQLdb模块代码示例:
    1. # 导入 MySQLdb模块
    2. import MySQLdb
    3. # 和服务器建立链接,host是服务器ip,我的MySQL数据库搭建在本机,默认的是127.0.0.1,. 鍥磋鎴戜滑@1point 3 acres
    4. # 用户、密码、数据库名称对应着照输就行了,默认的端口号是3306,charset是编码方式,
    5. # 默认的是utf8(也有可能是gbk,看安装的版本)。.鐣欏璁哄潧-涓€浜�-涓夊垎鍦�
    6. conn = MySQLdb.connect(host='127.0.0.1', user='root', passwd='yourPassword', db='dbname', port=3306, charset='utf8')
    7. # 建立cursor
    8. cur = conn.cursor(). 1point3acres.com/bbs
    9. # 通过对象cur的execute()方法执行SQL语句. 涓€浜�-涓夊垎-鍦帮紝鐙鍙戝竷
    10. cur.execute("select * from citeRelation where paperName = 'On Random Graph'")
    11. # fetchall()方法获得查询结果,返回的是一个list,可以直接这样查询:list[i][j],
    12. # i表示查询结果中的第i+1条record,j表示这条记录的第j+1个attribute(别忘了python从0开始计数)
    13. list = cur.fetchall()
    14. # 也可以进行delete,drop,insert,update等操作,比如:
    15. sql = "update studentCourseRecord set fail = 1 where studentID = '%s' and semesterID = '%s' and courseID = '%s'" %(studentID,course[0],course[1]). 涓€浜�-涓夊垎-鍦帮紝鐙鍙戝竷
    16. cur.execute(sql)
    17. # 与查询不同的是,执行完delete,insert,update这些语句后必须执行下面的命令才能成功更新数据库
    18. conn.commit()
    19. # 一如既往的,用完了之后记得关闭cursor,然后关闭链接. Waral 鍗氬鏈夋洿澶氭枃绔�,
    20. cur.close()
    21. conn.close()
    复制代码

    这样就实现了Python和数据库之间的交互。除了MySQL数据库外,python的PyGreSQL模块可以支持postgreSQL数据库,道理类似的。还有,如果你的网页里面包含了中文,设置编码格式会非常的麻烦,需要服务器、Python、数据库和数据库界面采用相同的编码格式才能不出现乱码,如果真的出现了中文乱码的问题,请相信,你不是一个人!!去google一下吧,成千上万的人碰到过这种问题。
    关于编码的问题,附一篇我看到的博文<python编码问题总结>:
    http://www.xprogrammer.com/1258.html

    后记:
    上面介绍了抓取网页数据的方法,抓取数据只是一小步,如何分析数据就是大学问了,欢迎讨论。
    上面有什么地方讲不清楚的,欢迎交流。

    特别注意:.鐣欏璁哄潧-涓€浜�-涓夊垎鍦�
    大规模抓取网站会给网站的服务器带来很大的压力,尽量选择服务器相对轻松的时段(比如凌晨)。网站很多,不要拿一亩三分地来做试验。. 涓€浜�-涓夊垎-鍦帮紝鐙鍙戝竷
    Python的time模块的sleep()方法可以让程序暂停一段时间,比如time.sleep(1)让程序运行到这里的时候暂停1秒。适时地暂停可以缓解服务器的压力,也可以保护自己的硬盘,正好码久了睡个觉,或者去趟gym,结果就出来了
    展开全文
  • python查找特定元素In this article, we would learn about arrays and how to code for an array question asked? So starting off we would first learn ... 本文,我们将学习数组以及如何为所问的数组问题...

    python查找特定元素

    In this article, we would learn about arrays and how to code for an array question asked? So starting off we would first learn about arrays i.e. what an array is?

    在本文中,我们将学习数组以及如何为所问的数组问题编码? 因此,我们首先要了解数组,即数组是什么?

    ARRAY: An array can be defined as a container object that is used to hold a fixed number of values of a single type of data. The main purpose of an array is to store multiple items of the same type together.

    ARRAY:数组可以定义为容器对象,用于容纳固定数量的单一类型数据的值。 数组的主要目的是将相同类型的多个项目存储在一起。

    arrays in python


    Image source: https://cdncontribute.geeksforgeeks.org/wp-content/uploads/array-2.png

    图片来源:https://cdncontribute.geeksforgeeks.org/wp-content/uploads/array-2.png

    This is the simple idea that you need to understand about the array, now starting with the simple question.

    这是您需要了解的关于数组的简单概念,现在从简单问题开始。

    Question:

    题:

    Suppose you are given with an array that contains ints. Your task is to return the number of 3 in the array.

    假设给定一个包含整数的数组。 您的任务是返回数组中的3。

    Example:

    例:

        Count3([1, 2, 3]) = 1
        Count3([1, 3, 3]) = 2
        Count9([1, 3, 9, 3, 3]) = 3
    
    

    Solution:

    解:

    Here we have to again consider a variable which is initially equal to zero to keep the count of a number of 3 and also our function is only defined for nums as our array would only contain integers as mentioned earlier.

    在这里,我们必须再次考虑一个初始为零的变量,以保持3的计数,并且我们的函数仅针对nums定义,因为我们的数组将仅包含整数(如前所述)。

    Code:

    码:

    def Count3(nums):
        count = 0
        for num in nums:
            if num == 3:
                count = count + 1
    
        return count
    
    print (Count3([1,2,3,4,3,3,3,]))
    
    

    Output

    输出量

    4
    
    
    

    翻译自: https://www.includehelp.com/python/program-to-find-the-occurrence-of-a-particular-number-in-an-array.aspx

    python查找特定元素

    展开全文
  • python表白程序-python告白程序

    千次阅读 2020-11-01 13:18:38
    程序结合数据抓取 + 微信自动发消息 + 定时任务,实现一个能每天自动定时给你心爱的 ta 发送:你们相识相恋天数 + 情话 + 我爱你的图片。 具体的消息如下。? 每天发送的消息格式如下: message = 亲爱的{}: 早上...
  • 安卓手机运行python程序

    千次阅读 2019-03-26 17:20:07
    用电脑写了一段python程序抓取某网站...有时候人又不电脑旁,所以希望找到一个能手机上运行Python程序的软件,随时随地抓取数据。度娘和谷哥了很久,找到三种类型的转件。一、手机上写手机专用的Python程序:...
  • python六大数据类型详解

    万次阅读 多人点赞 2019-10-13 21:07:18
    史上最全数据类型详解,详细介绍了Python3 六个标准的数据类型:Number(数值)、String(字符串)、List(列表)、Tuple(元组)、Set(集合)、Dictionary(字典)。六大数据类型的方法和常规操作。
  • 第一章 Python概述单元测试1、下列选项,不属于Python语言特点的是()。A、简单易学B、开源C、面向过程D、可移植性2、Python语言是一种()类型的编程语言。A、机器语言B、解释C、编译D、汇编语言3、Python语句...
  • 我是一名数据工程师,用SAS做分析超过5年后,决定走出舒适区,寻找其它有效的数据分析工具,很快我发现了Python! 我非常喜欢编程,这是我真正喜欢做的事情。事实证明,编程并没有想象的那么难。 我一周...
  • @本文来源于公众号:csdn2299,喜欢可以关注公众号 程序员学府 今天小编就为大家分享一篇解决Python3 被PHP程序调用执行返回乱码的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧 因为有一...
  • 这篇文章会让你了解到,Python有很多完善的工具包可以协助你完成重要的数据科学任务。 根据Indeed,Glassdoor和Dice等职场网站所提供的信息,与去年同期相比,随着各行各业越来越依赖于数据进行决策,商业对数据...
  • python数据分析学习路线

    千次阅读 2017-06-23 16:28:38
    Python是一种面向对象、直译式计算机程序设计语言,由Guido van Rossum于1989年底发明。...图片来源Python玩转数据 由于Python拥有非常丰富的库,使其在数据分析领域也有广泛的应用。由于Python
  • Python中使用sentinelsat包自动下载Sentinel系列数据

    千次阅读 多人点赞 2019-06-02 14:22:36
    Python使用sentinelsat包自动下载Sentinel系列数据 前言 近日博主需要下载上海市2018年的哨兵1A/B GDRH数据。 sentinelsat包简介 sentinelsat包安装 Sentinelsat包参数详解 批量下载上海市Sentinel 1程序 ...
  • 这篇文章主要介绍了在Python的Django框架更新数据库数据,对此Django框架提供了便利的插入和更新方法,需要的朋友可以参考下 先使用一些关键参数创建对象实例,如下: >>> p = Publisher(name='Apress', ...
  • 空间数据的处理常常是复杂而费时的,而且其过程具有很强的重复性,基于窗口的应用程序极大程度上限制了处理数据的能力,有必要进行自动化的处理。任何可以支持COM的脚本语言都可以执行ArcGIS的地理处理工具,如...
  • 董付国《Python程序设计基础 第2版》PDF首页 >计算机类字号:小中大评论:0 条评论:0 条Python程序设计基础 第2版【作 者】董付国编著【丛书名】计算机系列教材【形态项】 297【出版项】 北京:清华大学出版社 , ...
  • Python数据分析基础: 数据缺失值处理

    千次阅读 2020-10-31 21:56:01
    本篇开始分享如何使用Python进行数据分析,主要侧重介绍一些分析的方法和技巧,而对于pandas和numpy等Pyhon计算包的使用会问题提及,但不详细介绍。本篇我们来说说面对数据的缺失值,我们该如何处理。文末有.
  • Python 数据科学入门教程:Matplotlib

    万次阅读 多人点赞 2017-01-13 11:45:55
    Matplotlib 入门教程 来源:Introduction to Matplotlib and basic line 译者:飞龙 协议:CC BY-NC-SA 4.0 在线阅读 ...欢迎阅读 Python 3+ Matplotlib 系列教程。 本系列,我们将涉及
  • pandas 是基于NumPy 的一种工具, 名字很卡哇伊,来源是由“ Panel data”(面板数据,一个计量经济学名词)两个单词拼成的。pandas纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。主要...
  • 全网最全python爬虫+数据分析资源整理

    千次阅读 多人点赞 2021-04-29 14:08:36
    04丨Python科学计算:用NumPy快速处理数据 05丨Python科学计算:Pandas 06 | 学数据分析要掌握哪些基本概念? 07 | 用户画像:标签化就是数据的抽象能力 08 | 数据采集:如何自动化采集数据? 09丨数据采集:如何用...
  • python数据分析学习路线规划

    千次阅读 2017-12-28 21:17:55
    Python是一种面向对象、直译式计算机程序设计语言,由Guido van Rossum于1989年底发明。由于他简单、易学、免费...图片来源Python玩转数据 由于Python拥有非常丰富的库,使其在数据分析领域也有广泛的应用。由于Py
  • 最近学习,然后看到有别人发的Python期末考试,不知道具体的来源,猜测是某大学的课程,今天来学习一下。 一、选择题 1、下列是 python 合法标识符的是( B)。 A. 2variable B. variable2 C. $anothervar D. ...
  • 案例上手 Python 数据可视化

    万次阅读 多人点赞 2019-02-27 23:30:05
    课程亮点 ...数据可视化是数据分析和机器学习的重要环节,比如数据清洗、特征工程、机器学习、数据分析(特别是报告)、评估等环节都会用到“数据可视化”技术。 数据可视化同时还广泛存在于各...
  • 主要一个股票,使用时间序列模型研究按照下面的流程来研究一下其变化趋势,看看准不准,Python代码写的比较优美,学习者可以研读一下整个程序流程。 步骤: 准备数据 可视化数据、审查数据 处理数据 根据...
  • PythonPython核心编程

    万次阅读 多人点赞 2019-06-13 22:41:24
    Python核心编程 数据类型 数值类型(整数,浮点,布尔) 序列类型(字符串,列表,元组) 散列类型(字典,集合) 字节类型 a=bytes(‘123’)/a=b’123’ 字节数组bytearrary(‘123’) 数据类型的方法 字符串方法: ...
  • Python 数据科学入门教程:Pandas

    万次阅读 多人点赞 2018-02-02 20:13:43
    Python 和 Pandas 数据分析教程 原文:Data Analysis with Python and Pandas Tutorial Introduction 译者:飞龙 协议:CC BY-NC-SA 4.0 大家好,欢迎阅读 Python 和 Pandas 数据分析系列教程。 Pandas ...
  • Python:下载数据——JSON格式

    千次阅读 2019-08-22 21:23:49
    来源:《Python编程:从入门到实践》 文章目录1 制作交易收盘价走势图:JSON格式1.1 下载收盘价数据1.2 提取相关的数据1.3 将字符串转换为数字值1.4 绘制收盘价折线图1.5 时间序列特征初探1.6 收盘价均值1.7 收盘价...
  • Python数据挖掘-NLTK文本分析+jieba中文文本挖掘

    万次阅读 多人点赞 2018-02-21 00:16:23
    一、NLTK介绍及安装1.1 NLTK安装NLTK的全称是natural language toolkit,是一套基于python的...pip install nltknltk集成了语料与模型等的包管理器,通过在python解释器执行&gt;&gt;&gt; import...
  • 利用Python进行数据预处理

    千次阅读 2019-02-27 16:49:54
    数据导入到python环境:http://pandas.pydata.org/pandas-docs/stable/io.html(英文版) IO Tools (Text, CSV, HDF5, ...) The pandas I/O API is a set of top level reader functions accessed like pd.read...
  • Python中urllib2的数据标准化问题

    千次阅读 2017-06-13 14:52:02
    使用urllib2获取接口数据时一直显示服务器内部错误: urllib2.HTTPError: HTTP Error 500: Internal Server Error原因:请求数据传入错误。错误代码:import json import urllib2url = ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 69,647
精华内容 27,858
关键字:

在python程序中数据的来源可以是

python 订阅