当前位置: 首页 > news >正文

【Python】一些PEP提案(六):元类、默认 UTF-8、Web 开发

PEP 3115 – Metaclasses in Python 3000,元类

元类就是深度的魔法,99%的用户应该根本不必为此操心。
如果你想搞清楚 究竟是否需要用到元类,那么你就不需要它。
那些实际用到元类的人都非常清楚地知道他们需要做什么,而且根本不需要解释为什么要用元类。
—— TimPeters

这玩意我看了很久才看明白,因为Java和C++里都没有类似的概念。
推荐这篇文章Python黑魔法:元类和元编程 - 优刻得云计算的文章 - 知乎 写得真不错

概念

通俗来说,元类是控制类的创建的类
通过继承 type 可以定义自定义元类,核心是重写 __new__ 方法(负责创建类)或 __init__ 方法(负责初始化类)。

自定义元类的基本语法如下:

class MetaClass(type):def __new__(cls, name, bases, attrs):print(f"Creating class: {name}")return type.__new__(cls, name, bases, attrs)def __init__(cls, name, bases, attrs):print(f"Initializing class: {name}")type.__init__(cls, name, bases, attrs)class ClassA(object, metaclass=MetaClass):pass

元类不是父类。上面的代码可能会让你误认为ClassA的两个方法继承了MetaClass的,由于ClassA没有实例化,运行应该不会有任何打印。但实际上两行print都会打印。

Creating class: ClassA
Initializing class: ClassA

元类的两个方法是在创建类时调用的。逻辑比较相似。一般来说,如果操作需要影响类的 “创建结果”(如修改类名、基类、决定是否创建),应该放在 __new__;如果操作仅需 “基于已创建的类进行配置”,优先放在 __init__。概念是这样,但是具体还要看应用场景。

一个典型的元类的应用场景就是:单例模式

class SingletonMeta(type):_instances = {}def __call__(cls, *args, **kwargs):if cls not in cls._instances:cls._instances[cls] = super().__call__(*args, **kwargs)return cls._instances[cls]class Database(metaclass=SingletonMeta):def __init__(self):print("Connecting to database...")# 测试
db1 = Database()
db2 = Database()
print(db1 is db2)  # True

如上代码可以确保无论全局初始化多少个Database实例,实际上都指向同一个实例。

关于元类的更多内容,我会专门写篇文章介绍,这里就不说了。

PEP 3120 – Using UTF-8 as the default source encoding,默认 UTF-8

在 Python 2 中,源代码文件的默认编码是 ASCII。这意味着:

# Python 2 中,以下代码会出错(除非显式声明编码)
name = "你好"
print name

因为 “你好” 不是 ASCII 字符,Python 2 默认无法解析,会抛出:

SyntaxError: Non-ASCII character ...

为了解决这个问题,Python 2 引入了 PEP 263,允许在文件顶部用注释指定编码。比如utf-8就可以如此声明:

# -*- coding: utf-8 -*-
name = "你好"
print name

但是老这么写也不是个办法。既然大家写utf-8的最多,不如就改成默认这个吧。这就是PEP 3120所做的,Python 3 将源代码文件的默认编码从 ASCII 改为 UTF-8

  1. 所有 .py 文件默认以 UTF-8 编码读取。
  2. 无需再写 # -*- coding: utf-8 -*-(除非你用的是其他编码,如 GBK、Latin-1 等)。
  3. 可以直接在字符串、变量名(受限)、注释中使用中文、emoji、希腊字母等 Unicode 字符。

原有的编码声明得以保留,方便从utf-8切换其他编码。

PEP 3333 – Python Web Server Gateway Interface v1.0.1,Web 开发

今天如果用Python编写一个web应用,有各种各样的框架可以使用。而WSGI就是这些框架的基本接口。

当用户在浏览器访问 http://example.com/hello 时:

用户浏览器↓ (HTTP 请求)
Web 服务器(Gunicorn / uWSGI)↓ (调用 WSGI 应用)
Web 框架(Flask / Django)↓ (生成响应)
Web 服务器↓ (返回 HTTP 响应)
用户浏览器

服务器和框架之间,需要有某种接口进行协调,这就是WSGI(不考虑异步的场景,这里只说同步)只要框架返回一个符合WSGI 的 application,任何 WSGI 服务器(Gunicorn、uWSGI、mod_wsgi)都能运行它。

写一个简单的 app:

from wsgiref.simple_server import make_serverdef app(environ, start_response):status = '200 OK'headers = [('Content-Type', 'text/plain; charset=utf-8')]start_response(status, headers)return [b'Hello from WSGI server!']# 创建服务器,监听 8000 端口
with make_server('', 8000, app) as httpd:print("Serving on port 8000...")httpd.serve_forever()

运行以后在终端执行如下命令:

curl http://localhost:8000

收到服务器的响应:

Hello from WSGI server!

同时服务端也有打印:

127.0.0.1 - - [16/Aug/2025 14:54:45] "GET / HTTP/1.1" 200 23

这个 app 就是一个符合 WSGI 协议的 web 应用,同样的,我们不自己实现,而是使用一些 web 框架编写 app,也可以交给 wsgiref 运行,此时 wsgiref 就是服务器。我们以 flask 为例,仅仅修改 app 侧的代码,服务器侧完全不需要修改:

from flask import Flask
from wsgiref.simple_server import make_server
app = Flask(__name__)@app.route('/')
def hello():return 'Hello from Flask!'with make_server('', 8000, app.wsgi_app) as httpd:httpd.serve_forever()

flask的app.run,本质上也是使用wsgiref,因此会弹出类似警告:

WARNING: This is a development server. Do not use it in a production setting.

建议还是用现代的异步框架,比如uvicorn(服务器)+ fastapi(web应用)的组合

http://www.lryc.cn/news/622235.html

相关文章:

  • 【LeetCode 热题 100】55. 跳跃游戏
  • 开源数据发现平台:Amundsen Frontend Service 应用程序配置
  • Cursor 分析 bug 记录
  • 基于RobustVideoMatting(RVM)进行视频人像分割(torch、onnx版本)
  • 【机器学习深度学习】客观评估主观评估:落地场景权重比例
  • 四、图与网络模型
  • 大模型性能测试完全指南:从流式响应到多模态的深度实践
  • [激光原理与应用-286]:理论 - 波动光学 - 不同频段电磁波的特点与差异性
  • Docker Compose部署Clickhouse最新版
  • 区块链技术原理(13)-以太坊燃料费Gas
  • 力扣top100(day04-03)--二分查找
  • whisper 语种检测学习笔记
  • canoe面板中的进度条的使用
  • 机器学习——PCA(主成分分析)降维
  • 岩石薄片图像数据及标签-一些研究参考
  • Ceres Solver中 SetParameterization函数的完整详解
  • MySQL视图:虚拟表的强大用途与限制
  • Effective C++ 条款43:学习处理模板化基类内的名称
  • 农药化肥行业的 “智能化拐点”:边缘计算网关如何破解生产效率困局?
  • P4069 [SDOI2016] 游戏 Solution
  • 使用 Let’s Encrypt 免费申请泛域名 SSL 证书,并实现自动续期
  • Python匿名函数的具体用法
  • 蓝桥杯 二叉树
  • 企业级时序数据库选型指南:从传统架构向智能时序数据管理的转型之路
  • Java: Spring前端传递列表和数组限制大小256问题
  • ​Visual Studio 2013.5 ULTIMATE 中文版怎么安装?iso镜像详细步骤
  • [优选算法专题二滑动窗口——无重复字符的最长子串]
  • 介绍TCP的拥塞控制
  • 【Go语言-Day 36】构建专业命令行工具:`flag` 包入门与实战
  • 用Qt自带工具windeployqt快速打包程序