美文网首页
Python问题记录-1

Python问题记录-1

作者: 王国的荣耀 | 来源:发表于2021-03-10 21:58 被阅读0次

    python 项目生成requirements.txt等文件

    pip install pipreqs
    # 项目目录执行
    pipreqs ./
    

    python call 方法

    Call self as a function
    主要实现的是将类的对象当作函数直接调用

    # 
    class type(object):
          def __call__(self, *args, **kwargs): # real signature unknown
                  """ Call self as a function. """
                  pass
    

    call示例

    def __call__(self, environ, start_response):
            self.proxied = False
            script_name = environ.get('HTTP_X_SCRIPT_NAME', '')
            if script_name:
                self.proxied = True
                environ['SCRIPT_NAME'] = script_name
                path_info = environ.get('PATH_INFO', '')
                if path_info and path_info.startswith(script_name):
                    environ['PATH_INFO'] = path_info[len(script_name):]
    
            scheme = environ.get('HTTP_X_SCHEME', '')
            if scheme:
                environ['wsgi.url_scheme'] = scheme
            servr = environ.get('HTTP_X_FORWARDED_HOST', '')
            if servr:
                environ['HTTP_HOST'] = servr
                self.proxied = True
            return self.app(environ, start_response)
    

    Django、Tornado、Flask比较

    使用flask好久,感觉flask还是好用些。

    Django是Python 中最全能的 web 开发框架,走大而全的方向。它最出名的是其全自动化的管理后台:只需要使用起ORM,做简单的对象定义,它就能自动生成数据库结构、以及全功能的管理后台。不过Django提供的方便,也意味着Django内置的ORM跟框架内的其他模块耦合程度高,深度绑定了该框架,应用程序必须使用Django内置的ORM,否则就不能享受到框架内提供的种种基于其ORM的优秀特性。

    Tornado全称Tornado Web Server,是一个用Python语言写成的Web服务器兼Web应用框架。Tornado走的是少而精的方向,注重的是性能优越,它最出名的是异步非阻塞的服务器方式。(Tornado框架和服务器一起组成一个WSGI的全栈替代品。单独在WSGI容器中使用tornado web框架或者tornaod http服务器,有一定的局限性,为了最大化的利用tornado的性能,推荐同时使用tornaod的web框架和HTTP服务器。)

    Flask是一个使用 Python 编写的轻量级 Web 应用框架,也被称为 “microframework”,语法简单,部署很方便,整个框架自带了路径映射、模板引擎(Jinja2)、简单的数据库访问等web框架组件,支持WSGI协议(采用 Werkzeug)。Flask使用 BSD 授权。 Flask使用简单的核心,用 extension 增加其他功能,虽然没有默认使用的数据库、窗体验证工具,然而Flask保留了扩增的弹性,可以用Flask-extension加入ORM、窗体验证工具、文件上传、各种开放式身份验证技术这些功能。

    从性能上看Tornado 比Django、Flask等主流 Web 服务器框架相比有着明显的区别:它是非阻塞式服务器,速度相当快。然而 Tornado 相比 Django 和Flask属于较为原始的框架,插件少,许多内容需要自己去处理。而Flask插件多,文档非常专业,有专门的公司团队维护,对于快速开发很有效率。由于WSGI协议的存在,可以结合 Tornado 的服务器异步特性、并发处理能力和Flask的文档和扩展能力为一体。虽然像Django,Flask框架都有自己实现的简单的WSGI服务器,但一般用于服务器调试,生产环境下建议用其他WSGI服务器,比如Nginx+uwsgi+Django方式。

    参考

    python-tornado简单使用
    Python的web架构之Tornado+Flask

    python 装饰器

    装饰器能够在那个函数执行前或者执行后分别运行一些代码,使得可以再装饰器里面访问并修改原函数的参数以及返回值,以实现约束定义、调试程序、注册函数等目标。装饰器一般返回一个包装器(wrapper),而functools.wraps就是装饰包装器的装饰器。

    自己创建一个装饰器

    def a_new_decorator(a_func):
        def wrapTheFunction():
            print("I am doing some boring work before executing a_func()")
            a_func()
            print("I am doing some boring work after executing a_func()")
            return wrapTheFunction
    
    def a_function_requiring_decoration():
        print("I am the function which needs some decoration to remove my foul smell")
    
    a_function_requiring_decoration()
    #outputs: "I am the function which needs some decoration to remove my foul smell"
    
    a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)
    #now a_function_requiring_decoration is wrapped by wrapTheFunction()
    
    a_function_requiring_decoration()
    #outputs:I am doing some boring work before executing a_func()
    #        I am the function which needs some decoration to remove my foul smell
    #        I am doing some boring work after executing a_func()
    
    from functools import wraps
    def a_new_decorator(a_func):
        @wraps(a_func)
        def wrapTheFunction():
            print("I am doing some boring work before executing a_func()")
            a_func()
            print("I am doing some boring work after executing a_func()")
            return wrapTheFunction
    
    @a_new_decorator
    def a_function_requiring_decoration():
        """Hey you! Decorate me!"""
        print("I am the function which needs some decoration to "
              "remove my foul smell")
    
    a_function_requiring_decoration()
    
    a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)
    print(a_function_requiring_decoration.__name__)
    

    输出结果为

    I am doing some boring work before executing a_func()
    I am the function which needs some decoration to remove my foul smell
    I am doing some boring work after executing a_func()
    
    a_function_requiring_decoration
    

    python 修饰符@

    修饰符@的作用是为现有函数增加额外的功能,常用于插入日志、性能测试、事务处理等等。
    创建函数修饰符的规则:
    (1)修饰符是一个函数
    (2)修饰符取被修饰函数为参数
    (3)修饰符返回一个新函数
    (4)修饰符维护被维护函数的签名

    修饰符@是一个函数

    def log(func):
        def wrapper():
            print('log开始 ...')
            func()
            print('log结束 ...')
        return wrapper
    
    @log
    def run_func():
        print('run_func ..')
    
    run_func()
    #log开始 ...
    #run_func ..
    #log结束 ...
    

    修饰符@维护被维护函数的签名

    使用functools模块提供的修改函数属性的方法wraps

    from functools import wraps
    
    def log(func):
        @wraps(func)
        def wrapper():
            print('log开始 ...')
            func()
            print('log结束 ...')
        return wrapper
        
    @log
    def test1():
        print('test1 ..')
    
    def test2():
        print('test2 ..')
    
    print(test1.__name__)
    print(test2.__name__)
    
    #test1
    #test2
    

    被修饰函数带参数

    from functools import wraps
    
    def log(func):
        @wraps(func)
        def wrapper(*args,**kwargs):
            print('log开始 ...',func.__name__)
            ret = func(*args,**kwargs)
            print('log结束 ...')
            return ret
        return wrapper
        
    @log
    def test1(s):
        print('test1 ..', s)
        return s
    
    @log
    def test2(s1, s2):
        print('test2 ..', s1, s2)
        return s1 + s2
    
    
    test1('a')
    test2('a','bc')
    

    参考

    python 函数修饰符@

    python 打开文件

    f = file(name[, mode[, buffering]])
    入口参数: name 文件名
    mode 选项,字符串
    buffering 是否缓冲 (0=不缓冲,1=缓冲, >1的int数=缓冲区大小)
    返回值 : 文件对象
    mode 选项:
    "r" 以读方式打开,只能读文件 , 如果文件不存在,会发生异常
    "w" 以写方式打开,只能写文件, 如果文件不存在,创建该文件
    如果文件已存在,先清空,再打开文件
    "rb" 以二进制读方式打开,只能读文件 , 如果文件不存在,会发生异常
    "wb" 以二进制写方式打开,只能写文件, 如果文件不存在,创建该文件
    如果文件已存在,先清空,再打开文件
    "rt" 以文本读方式打开,只能读文件 , 如果文件不存在,会发生异常
    "wt" 以文本写方式打开,只能写文件, 如果文件不存在,创建该文件
    如果文件已存在,先清空,再打开文件
    "rb+" 以二进制读方式打开,可以读、写文件 , 如果文件不存在,会发生异常
    "wb+" 以二进制写方式打开,可以读、写文件, 如果文件不存在,创建该文件
    如果文件已存在,先清空,再打开文件

    python3.8使用flask_wtf时产生的cannot import name 'url_encode'问题

    werkzeug 版本过高,导致问题出现;安装werkzeug的低版本即可解决问题
    pip install werkzeug==0.16.0

    flask 渲染html

    from flask import render_template
    
    @app.route('/user/')
    def user():
        return render_template('user.html')
    if __name__ == '__main__':
        app.run(debug=True)
    
    
    # user.html 
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>这是用户中心</title>
        <h1>这是用户中心! </h1>
    </head>
    <body>
    
    </body>
    </html>
    
    

    python 3.7 async=True, get_object=False, no_input=False):

    pip install pyspider
    pyspider
    ➜  Containers Pyspider
    Traceback (most recent call last):
      File "/Library/Frameworks/Python.framework/Versions/3.8/bin/Pyspider", line 5, in <module>
        from pyspider.run import main
      File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pyspider/run.py", line 231
        async=True, get_object=False, no_input=False):
        ^
    

    原因是python3.7中async已经变成了关键字。因此出现这个错误。
    修改方式是手动替换一下

    下面位置的async改为mark_async
    /usr/local/lib/python3.7/site-packages/pyspider/run.py 的231行、245行(两个)、365行
    /usr/local/lib/python3.7/site-packages/pyspider/webui/app.py 的95行
    /usr/local/lib/python3.7/site-packages/pyspider/fetcher/tornado_fetcher.py 的81行、89行(两个)、95行、117行

     ~ pyspider
    Traceback (most recent call last):
      File "/Library/Frameworks/Python.framework/Versions/3.8/bin/pyspider", line 8, in <module>
        sys.exit(main())
      File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pyspider/run.py", line 754, in main
        cli()
      File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/click/core.py", line 829, in __call__
        return self.main(*args, **kwargs)
      File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/click/core.py", line 782, in main
        rv = self.invoke(ctx)
      File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/click/core.py", line 1236, in invoke
        return Command.invoke(self, ctx)
      File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
        return ctx.invoke(self.callback, **ctx.params)
      File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/click/core.py", line 610, in invoke
        return callback(*args, **kwargs)
      File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/click/decorators.py", line 21, in new_func
        return f(get_current_context(), *args, **kwargs)
      File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pyspider/run.py", line 165, in cli
        ctx.invoke(all)
      File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/click/core.py", line 610, in invoke
        return callback(*args, **kwargs)
      File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/click/decorators.py", line 21, in new_func
        return f(get_current_context(), *args, **kwargs)
      File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pyspider/run.py", line 467, in all
        threads.append(run_in(ctx.invoke, phantomjs, **phantomjs_config))
      File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pyspider/libs/utils.py", line 68, in run_in_subprocess
        thread.start()
      File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/multiprocessing/process.py", line 121, in start
        self._popen = self._Popen(self)
      File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/multiprocessing/context.py", line 224, in _Popen
        return _default_context.get_context().Process._Popen(process_obj)
      File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/multiprocessing/context.py", line 284, in _Popen
        return Popen(process_obj)
      File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/multiprocessing/popen_spawn_posix.py", line 32, in __init__
        super().__init__(process_obj)
      File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/multiprocessing/popen_fork.py", line 19, in __init__
        self._launch(process_obj)
      File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/multiprocessing/popen_spawn_posix.py", line 47, in _launch
        reduction.dump(process_obj, fp)
      File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/multiprocessing/reduction.py", line 60, in dump
        ForkingPickler(file, protocol).dump(obj)
    _pickle.PicklingError: Can't pickle <function cli at 0x7fe59a5735e0>: it's not the same object as pyspider.run.cli
    

    解决方法:使用pipenv

    参考

    https://www.cnblogs.com/jiguanghover/p/11364513.html

    python 多线程实现同步的四种方式

    https://www.cnblogs.com/zhumengke/articles/10825242.html

    Python raise

    http://c.biancheng.net/view/2360.html

    Python functools.partial

    partial adj. 局部的;偏爱的;不公平的
    Python 提供了一个 functools 的模块,该模块为高阶函数提供支持,partial 就是其中的一个函数

    def  add(x, y):
        return x + y
    
     add(3, y=2)
     add(4, y=2)
     add(5, y=2)
    
    
    def plus(x, y=2):
        return add(x, y)
    
    plus(3)
    plus(4)
    plus(5)
    
    
    from functools import partial
    plus = partial(add, y=2)
    

    partial 接收函数 add 作为参数,固定 add 的参数 y=2,并返回一个新的函数给 plus。简单而言,partial 函数的功能就是:把一个函数的某些参数给固定住,返回一个新的函数。

    参考

    python标准库--functools.partial

    端口转发

    server{
     listen 80;
     server_name  tomcat.shaochenfeng.com;
     index  index.php index.html index.htm;
    
     location / {
       proxy_pass  http://127.0.0.1:8080; # 转发规则
       proxy_set_header Host $proxy_host; # 修改转发请求头,让8080端口的应用可以受到真实的请求
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     }
    }
    

    相关文章

      网友评论

          本文标题:Python问题记录-1

          本文链接:https://www.haomeiwen.com/subject/ncqaxltx.html