1 cgi fastcgi wsgi uwsgi uWSGI 分别是什么?
2 如何自定制上下文管理器
3 Python是值传递还是引用传递
1 cgi fastcgi wsgi uwsgi uWSGI 分别是什么?
1 CGI:通用网关接口(Common Gateway Interface/CGI),CGI描述了服务器和请求处理程序之间传输数据的一种标准
-所有bs架构软件都是遵循CGI协议的
-一句话总结: 一个标准,定义了客户端服务器之间传递数据的标准,所有bs架构软件都遵循这个协议
2 FastCGI:快速通用网关接口(Fast Common Gateway Interface/FastCGI)是一种让交互程序与
Web服务器通信的协议。FastCGI是早期通用网关接口(CGI)的增强版本
-FastCGI致力于减少网页服务器与CGI程序之间互动的开销,从而使服务器可以同时处理更多的网页请求
-常见的fastcgi服务器:Apache,Nginx,Microsoft IIS
-一句话总结:CGI的升级版
3 WSGI:Python Web Server Gateway Interface,缩写为WSGI,Python定义的Web服务器和
Web应用程序或框架之间的一种通用的接口
-一句话总结: 为Python定义的web服务器和web框架之间的接口标准
-符合wsgi协议的web服务器:uWSGI,wsgiref,gunicorn,werkzeug
-http请求进来到符合wsgi协议的web服务器----》会被服务器把http请求转换成python的对象(environ,start_response)
4 uWSGI:符合wsgi协议的web服务器,用c写的,性能比较高,咱们通常用来部署django,flask
-一句话总结:一个Web Server(web服务器),即一个实现了WSGI协议的服务器,处理发来的请求及返回响应。
5 uwsgi:uWSGI服务器实现的独有的协议,用于定义传输信息的类型,是用于前端服务器与 uwsgi 的通信规范
-一句话总结: uWSGI自有的一个协议
uWSGI:web服务器,等同于wsgiref
uwsgi:uWSGI自有的协议
6 asgi是wsgi的扩展异步Python标准,比只能同步的wsgi性能更好,且可支持websocket,
在 Django3+ 和 Flask2+ 中得到支持。
目前常用的asgi服务器包括:Uvicorn 、Daphne 、Hypercorn ,
7 符合WSGI协议的web服务器
wsgiref,werkzeug(一个是符合wsgi协议的web服务器+工具包(封装了一些东西))
uWSGI 用c语言写的,性能比较高
gunicorn:python写的
8 web服务器到底是什么?服务器中间件
-客户端(浏览器,app) 跟 服务端(web框架)之间的东西,服务器中间件
- nginx apache 是一类东西,就是做请求转发,符合fastcgi服务器
- uWSGI,gunicorn 只针对于python的web框架
- tomcat,jboss,weblogic 只针对java的web框架
- php-fpm 针对于php的框架
# https://www.jianshu.com/p/5858dbd275c9
# https://baijiahao.baidu.com/s?id=1718367047580754624&wfr=spider&for=pc
# https://www.cnblogs.com/daminghuahua/p/16526900.html
9 nginx把请求转发给 uwsgi
-如果uwsgi配置是这样的:
<uwsgi>
<http>0.0.0.0:8080</http> <!-- 内部端口,自定义 -->
<chdir>/soft/</chdir> <!-- 项目路径 -->
<module>luffy_api.wsgi</module> <!-- luffy_api为wsgi.py所在目录名-->
<processes>4</processes> <!-- 进程数 -->
</uwsgi>
-nginx配置是:
location / {
proxy_pass http://127.0.0.1:8080;
}
-如果uwsgi配置是这样的
<uwsgi>
<socket>0.0.0.0:8080</socket> <!-- uWSGI自有协议 -->
<chdir>/soft/</chdir> <!-- 项目路径 -->
<module>luffy_api.wsgi</module> <!-- luffy_api为wsgi.py所在目录名-->
<processes>4</processes> <!-- 进程数 -->
</uwsgi>
-nginx配置是:
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8888;
}
2 如何自定制上下文管理器
"""
上下文管理器(Context Manager)是Python中的一种编程模式,用于管理资源的获取和释放。
它通过定义一个特定的上下文环境,确保在进入和离开这个环境时,相关资源会被正确地获取和释放。
上下文管理器通常与with语句一起使用,以确保在代码块执行后清理资源。
Python中的文件对象就是一个上下文管理器,因此可以使用with语句来打开和关闭文件。
"""
- python的一种编程模式,用于进入和退出之后自动执行一些代码的场景
- 一个类如果实现了__enter__和___exit__方法,那么这个对象就支持上下文管理协议,即with语句
- 上下文管理协议适用于那些进入和退出之后自动执行一些代码的场景,
比如文件、网络连接、数据库连接或使用锁,使用事务的编码场景等
- session--->创建session对象--->最后用完要调用commit,close
-如何使用
from sqlalchemy.orm import scoped_session
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from models import Boy
engine = create_engine(
"mysql+pymysql://root:123@127.0.0.1:3306/sqlalchemy01?charset=utf8",
max_overflow=0, # 超过连接池大小外最多创建的连接
pool_size=5, # 连接池大小
pool_timeout=30, # 池中没有线程最多等待的时间,否则报错
pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
)
Session = sessionmaker(bind=engine) # 把引擎传入
session = scoped_session(Session)
class ComonSession:
def __enter__(self):
print('进入with语句块时执行此方法,此方法如果有返回值会赋值给as声明的变量')
self.session=session
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.session.commit()
self.session.close()
# session.add(user)
# session.commit()
# session.close()
with ComonSession() as sess:
sess.session.add(user)
# res=sess.query(Boy).filter_by(name='lqz').all()
# print(res)
print('我完事了')
- 用上下文管理器管理类 sqlalchemy 的链接对象session
- django中有些sql使用orm写不出来---》我们用原生sql写,用原生sql写的时候,
获取cursor对象的时候,就使用了上下文管理器
from django.db import connection
cur=connection.cursor()
cur.execute('select distinct id, book_name from test_book')
print(cur.fetchall())
cur.close()
with connection.cursor() as cur:
cur.execute('select distinct id, book_name from test_book')
2.1 定制锁的上下文管理器
import time
from threading import Lock, Thread
lock = Lock()
class CommonLock:
def __enter__(self):
self.lock=lock
self.lock.acquire()
return self.lock
def __exit__(self, exc_type, exc_val, exc_tb):
self.lock.release()
a = 1
def task():
with CommonLock() as lock:
global a
# a=a+1
b = a
b += 1
time.sleep(0.1)
a = b
if __name__ == '__main__':
l = []
for i in range(10):
t = Thread(target=task)
t.start()
l.append(t)
for t in l:
t.join()
print(a)
3 Python是值传递还是引用传递
- 严格意义上来说,python既不是值传递,也不是引用传递,python是自己的传递方式,规则是:
如果传递的是不可变类型,在函数中修改,就不会影响原来的变量
如果传递的是可变数据类型,在函数中修改,会影响原来的变量,修改,而不是重新赋值
- python一切皆对象---》(你不要说)内部一切皆引用[地址](对象本质就是地址,就是引用)
- 什么是值,什么是引用
-值就是一个变量=具体的值(一块内存空间放着这个变量的值)
-引用是一个变量=内存地址(内存地址指向了值)
-所有python才有了可变和不可变类型
- 什么是值传递 什么是引用传递
-如果是值传递,函数中修改了传递的值,不会影响原来的
-如果是引用传递,函数中修改了传递的引用,就会影响原来的
在Python中,参数的传递方式既不是纯粹的值传递(pass by value)
也不是纯粹的引用传递(pass by reference)。Python 的参数传递采用的是“对象引用传递”,
也称为“对象的地址传递”。
这意味着传递一个参数到一个函数时,实际上传递的是该对象的引用(在内存中的地址)。
因此,函数内部对参数的修改可能影响到原始对象。
然而,Python 中的可变对象和不可变对象的行为是不同的。
1. **不可变对象(比如整数、字符串、元组):**
不可变对象在传递过程中是值传递的,函数内部的修改不会影响到原始对象。
"""
def modify_value(x):
x += 10
a = 5
modify_value(a)
print(a) # 输出仍然是 5
"""
2. **可变对象(比如列表、字典):**
可变对象在传递过程中是引用传递的,函数内部的修改会影响到原始对象。
"""
def modify_list(lst):
lst.append(4)
my_list = [1, 2, 3]
modify_list(my_list)
print(my_list) # 输出为 [1, 2, 3, 4]
"""
is 比较的是两个对象的内存地址,因为x和y都是贴向相同,所以判断为True。
那么为什么不能用==呢,==只是比较对象的值,不能判断两个变量贴向的对象是否相同。
故而:可以认为Python的参数传递方式是“按对象传递(pass by object)”,即传递的是对象的引用。
参考文章:
https://zhuanlan.zhihu.com/p/69746955