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

PEP 3115 -- Metaclasses in Python 3000,元类

元类就是深度的魔法,99%的用户应该根本不必为此操心。

如果你想搞清楚 究竟是否需要用到元类,那么你就不需要它。

那些实际用到元类的人都非常清楚地知道他们需要做什么,而且根本不需要解释为什么要用元类。

------ TimPeters

这玩意我看了很久才看明白,因为Java和C++里都没有类似的概念。

推荐这篇文章Python黑魔法:元类和元编程 - 优刻得云计算的文章 - 知乎 写得真不错

概念

通俗来说,元类是控制类的创建的类

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

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

python 复制代码
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都会打印。

bash 复制代码
Creating class: ClassA
Initializing class: ClassA

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

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

python 复制代码
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 复制代码
# Python 2 中,以下代码会出错(除非显式声明编码)
name = "你好"
print name

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

bash 复制代码
SyntaxError: Non-ASCII character ...

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

bash 复制代码
# -*- 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 时:

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

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

写一个简单的 app:

python 复制代码
from wsgiref.simple_server import make_server

def 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()

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

bash 复制代码
curl http://localhost:8000

收到服务器的响应:

bash 复制代码
Hello from WSGI server!

同时服务端也有打印:

bash 复制代码
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 侧的代码,服务器侧完全不需要修改:

python 复制代码
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,因此会弹出类似警告:

python 复制代码
WARNING: This is a development server. Do not use it in a production setting.

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

相关推荐
白露与泡影1 分钟前
Spring容器初始化源码解析
java·python·spring
码界筑梦坊27 分钟前
98-基于Python的网上厨房美食推荐系统
开发语言·python·美食
光爷不秃37 分钟前
Go语言中安全停止Goroutine的三种方法及设计哲学
开发语言·安全·golang
参宿740 分钟前
electron之win/mac通知免打扰
java·前端·electron
计算机源码社1 小时前
分享一个基于Hadoop的二手房销售签约数据分析与可视化系统,基于Python可视化的二手房销售数据分析平台
大数据·hadoop·python·数据分析·毕业设计项目·毕业设计源码·计算机毕设选题
lpfasd1231 小时前
非中文语音视频自动生成中文字幕的完整实现方案
开发语言·python
石小石Orz1 小时前
性能提升60%:前端性能优化终极指南
前端·性能优化
夏日不想说话1 小时前
API请求乱序?深入解析 JS 竞态问题
前端·javascript·面试
大志说编程1 小时前
LangChain框架入门15:深度解析Retrievers检索器组件
python·langchain·llm
zhaoolee1 小时前
通过rss订阅小红书,程序员将小红书同步到自己的github主页
前端