Python問題記錄-1

python 項目生成requirements.txt等文件

pip install pipreqs
# 項目目錄執(zhí)行
pipreqs ./

python call 方法

Call self as a function
主要實現(xiàn)的是將類的對象當作函數(shù)直接調(diào)用

# 
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 開發(fā)框架,走大而全的方向。它最出名的是其全自動化的管理后臺:只需要使用起ORM,做簡單的對象定義,它就能自動生成數(shù)據(jù)庫結(jié)構(gòu)、以及全功能的管理后臺。不過Django提供的方便,也意味著Django內(nèi)置的ORM跟框架內(nèi)的其他模塊耦合程度高,深度綁定了該框架,應(yīng)用程序必須使用Django內(nèi)置的ORM,否則就不能享受到框架內(nèi)提供的種種基于其ORM的優(yōu)秀特性。

Tornado全稱Tornado Web Server,是一個用Python語言寫成的Web服務(wù)器兼Web應(yīng)用框架。Tornado走的是少而精的方向,注重的是性能優(yōu)越,它最出名的是異步非阻塞的服務(wù)器方式。(Tornado框架和服務(wù)器一起組成一個WSGI的全棧替代品。單獨在WSGI容器中使用tornado web框架或者tornaod http服務(wù)器,有一定的局限性,為了最大化的利用tornado的性能,推薦同時使用tornaod的web框架和HTTP服務(wù)器。)

Flask是一個使用 Python 編寫的輕量級 Web 應(yīng)用框架,也被稱為 “microframework”,語法簡單,部署很方便,整個框架自帶了路徑映射、模板引擎(Jinja2)、簡單的數(shù)據(jù)庫訪問等web框架組件,支持WSGI協(xié)議(采用 Werkzeug)。Flask使用 BSD 授權(quán)。 Flask使用簡單的核心,用 extension 增加其他功能,雖然沒有默認使用的數(shù)據(jù)庫、窗體驗證工具,然而Flask保留了擴增的彈性,可以用Flask-extension加入ORM、窗體驗證工具、文件上傳、各種開放式身份驗證技術(shù)這些功能。

從性能上看Tornado 比Django、Flask等主流 Web 服務(wù)器框架相比有著明顯的區(qū)別:它是非阻塞式服務(wù)器,速度相當快。然而 Tornado 相比 Django 和Flask屬于較為原始的框架,插件少,許多內(nèi)容需要自己去處理。而Flask插件多,文檔非常專業(yè),有專門的公司團隊維護,對于快速開發(fā)很有效率。由于WSGI協(xié)議的存在,可以結(jié)合 Tornado 的服務(wù)器異步特性、并發(fā)處理能力和Flask的文檔和擴展能力為一體。雖然像Django,F(xiàn)lask框架都有自己實現(xiàn)的簡單的WSGI服務(wù)器,但一般用于服務(wù)器調(diào)試,生產(chǎn)環(huán)境下建議用其他WSGI服務(wù)器,比如Nginx+uwsgi+Django方式。

參考

python-tornado簡單使用
Python的web架構(gòu)之Tornado+Flask

python 裝飾器

裝飾器能夠在那個函數(shù)執(zhí)行前或者執(zhí)行后分別運行一些代碼,使得可以再裝飾器里面訪問并修改原函數(shù)的參數(shù)以及返回值,以實現(xiàn)約束定義、調(diào)試程序、注冊函數(shù)等目標。裝飾器一般返回一個包裝器(wrapper),而functools.wraps就是裝飾包裝器的裝飾器。

自己創(chuàng)建一個裝飾器

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__)

輸出結(jié)果為

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 修飾符@

修飾符@的作用是為現(xiàn)有函數(shù)增加額外的功能,常用于插入日志、性能測試、事務(wù)處理等等。
創(chuàng)建函數(shù)修飾符的規(guī)則:
(1)修飾符是一個函數(shù)
(2)修飾符取被修飾函數(shù)為參數(shù)
(3)修飾符返回一個新函數(shù)
(4)修飾符維護被維護函數(shù)的簽名

修飾符@是一個函數(shù)

def log(func):
    def wrapper():
        print('log開始 ...')
        func()
        print('log結(jié)束 ...')
    return wrapper

@log
def run_func():
    print('run_func ..')

run_func()
#log開始 ...
#run_func ..
#log結(jié)束 ...

修飾符@維護被維護函數(shù)的簽名

使用functools模塊提供的修改函數(shù)屬性的方法wraps

from functools import wraps

def log(func):
    @wraps(func)
    def wrapper():
        print('log開始 ...')
        func()
        print('log結(jié)束 ...')
    return wrapper
    
@log
def test1():
    print('test1 ..')

def test2():
    print('test2 ..')

print(test1.__name__)
print(test2.__name__)

#test1
#test2

被修飾函數(shù)帶參數(shù)

from functools import wraps

def log(func):
    @wraps(func)
    def wrapper(*args,**kwargs):
        print('log開始 ...',func.__name__)
        ret = func(*args,**kwargs)
        print('log結(jié)束 ...')
        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 函數(shù)修飾符@

python 打開文件

f = file(name[, mode[, buffering]])
入口參數(shù): name 文件名
mode 選項,字符串
buffering 是否緩沖 (0=不緩沖,1=緩沖, >1的int數(shù)=緩沖區(qū)大小)
返回值 : 文件對象
mode 選項:
"r" 以讀方式打開,只能讀文件 , 如果文件不存在,會發(fā)生異常
"w" 以寫方式打開,只能寫文件, 如果文件不存在,創(chuàng)建該文件
如果文件已存在,先清空,再打開文件
"rb" 以二進制讀方式打開,只能讀文件 , 如果文件不存在,會發(fā)生異常
"wb" 以二進制寫方式打開,只能寫文件, 如果文件不存在,創(chuàng)建該文件
如果文件已存在,先清空,再打開文件
"rt" 以文本讀方式打開,只能讀文件 , 如果文件不存在,會發(fā)生異常
"wt" 以文本寫方式打開,只能寫文件, 如果文件不存在,創(chuàng)建該文件
如果文件已存在,先清空,再打開文件
"rb+" 以二進制讀方式打開,可以讀、寫文件 , 如果文件不存在,會發(fā)生異常
"wb+" 以二進制寫方式打開,可以讀、寫文件, 如果文件不存在,創(chuàng)建該文件
如果文件已存在,先清空,再打開文件

python3.8使用flask_wtf時產(chǎn)生的cannot import name 'url_encode'問題

werkzeug 版本過高,導(dǎo)致問題出現(xiàn);安裝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已經(jīng)變成了關(guān)鍵字。因此出現(xiàn)這個錯誤。
修改方式是手動替換一下

下面位置的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 多線程實現(xiàn)同步的四種方式

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

Python raise

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

Python functools.partial

partial adj. 局部的;偏愛的;不公平的
Python 提供了一個 functools 的模塊,該模塊為高階函數(shù)提供支持,partial 就是其中的一個函數(shù)

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 接收函數(shù) add 作為參數(shù),固定 add 的參數(shù) y=2,并返回一個新的函數(shù)給 plus。簡單而言,partial 函數(shù)的功能就是:把一個函數(shù)的某些參數(shù)給固定住,返回一個新的函數(shù)。

參考

python標準庫--functools.partial

端口轉(zhuǎn)發(fā)

server{
 listen 80;
 server_name  tomcat.shaochenfeng.com;
 index  index.php index.html index.htm;

 location / {
   proxy_pass  http://127.0.0.1:8080; # 轉(zhuǎn)發(fā)規(guī)則
   proxy_set_header Host $proxy_host; # 修改轉(zhuǎn)發(fā)請求頭,讓8080端口的應(yīng)用可以受到真實的請求
   proxy_set_header X-Real-IP $remote_addr;
   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容