http内置库(1)-HTTPStatus

http内置库文档:https://docs.python.org/zh-cn/3.10/library/http.html

http 是一个包,它收集了多个用于处理超文本传输协议的模块:

  • http.client 是一个底层的 HTTP 协议客户端;对于高层级的 URL 访问请使用 urllib.request
  • http.server 包含基于 socketserver 的基本 HTTP 服务类
  • http.cookies 包含一些有用来实现通过cookies 进行状态管理的工具
  • http.cookiejar 提供了 cookies 的持久化

http 也是一个通过 http.HTTPStatus 枚举定义了一些 HTTP 状态码以及相关联消息的模块

1、源码

from enum import IntEnum

__all__ = ['HTTPStatus']


class HTTPStatus(IntEnum):
    def __new__(cls, value, phrase, description=''):
        obj = int.__new__(cls, value)
        obj._value_ = value

        obj.phrase = phrase
        obj.description = description
        return obj

    # informational
    CONTINUE = 100, 'Continue', 'Request received, please continue'
    SWITCHING_PROTOCOLS = (101, 'Switching Protocols',
            'Switching to new protocol; obey Upgrade header')
    PROCESSING = 102, 'Processing'
    EARLY_HINTS = 103, 'Early Hints'

    # success
    OK = 200, 'OK', 'Request fulfilled, document follows'
    CREATED = 201, 'Created', 'Document created, URL follows'
    ACCEPTED = (202, 'Accepted',
        'Request accepted, processing continues off-line')
    NON_AUTHORITATIVE_INFORMATION = (203,
        'Non-Authoritative Information', 'Request fulfilled from cache')
    NO_CONTENT = 204, 'No Content', 'Request fulfilled, nothing follows'
    RESET_CONTENT = 205, 'Reset Content', 'Clear input form for further input'
    PARTIAL_CONTENT = 206, 'Partial Content', 'Partial content follows'
    MULTI_STATUS = 207, 'Multi-Status'
    ALREADY_REPORTED = 208, 'Already Reported'
    IM_USED = 226, 'IM Used'

    # redirection
    MULTIPLE_CHOICES = (300, 'Multiple Choices',
        'Object has several resources -- see URI list')
    MOVED_PERMANENTLY = (301, 'Moved Permanently',
        'Object moved permanently -- see URI list')
    FOUND = 302, 'Found', 'Object moved temporarily -- see URI list'
    SEE_OTHER = 303, 'See Other', 'Object moved -- see Method and URL list'
    NOT_MODIFIED = (304, 'Not Modified',
        'Document has not changed since given time')
    USE_PROXY = (305, 'Use Proxy',
        'You must use proxy specified in Location to access this resource')
    TEMPORARY_REDIRECT = (307, 'Temporary Redirect',
        'Object moved temporarily -- see URI list')
    PERMANENT_REDIRECT = (308, 'Permanent Redirect',
        'Object moved permanently -- see URI list')

    # client error
    BAD_REQUEST = (400, 'Bad Request',
        'Bad request syntax or unsupported method')
    UNAUTHORIZED = (401, 'Unauthorized',
        'No permission -- see authorization schemes')
    PAYMENT_REQUIRED = (402, 'Payment Required',
        'No payment -- see charging schemes')
    FORBIDDEN = (403, 'Forbidden',
        'Request forbidden -- authorization will not help')
    NOT_FOUND = (404, 'Not Found',
        'Nothing matches the given URI')
    METHOD_NOT_ALLOWED = (405, 'Method Not Allowed',
        'Specified method is invalid for this resource')
    NOT_ACCEPTABLE = (406, 'Not Acceptable',
        'URI not available in preferred format')
    PROXY_AUTHENTICATION_REQUIRED = (407,
        'Proxy Authentication Required',
        'You must authenticate with this proxy before proceeding')
    REQUEST_TIMEOUT = (408, 'Request Timeout',
        'Request timed out; try again later')
    CONFLICT = 409, 'Conflict', 'Request conflict'
    GONE = (410, 'Gone',
        'URI no longer exists and has been permanently removed')
    LENGTH_REQUIRED = (411, 'Length Required',
        'Client must specify Content-Length')
    PRECONDITION_FAILED = (412, 'Precondition Failed',
        'Precondition in headers is false')
    REQUEST_ENTITY_TOO_LARGE = (413, 'Request Entity Too Large',
        'Entity is too large')
    REQUEST_URI_TOO_LONG = (414, 'Request-URI Too Long',
        'URI is too long')
    UNSUPPORTED_MEDIA_TYPE = (415, 'Unsupported Media Type',
        'Entity body in unsupported format')
    REQUESTED_RANGE_NOT_SATISFIABLE = (416,
        'Requested Range Not Satisfiable',
        'Cannot satisfy request range')
    EXPECTATION_FAILED = (417, 'Expectation Failed',
        'Expect condition could not be satisfied')
    IM_A_TEAPOT = (418, 'I\'m a Teapot',
        'Server refuses to brew coffee because it is a teapot.')
    MISDIRECTED_REQUEST = (421, 'Misdirected Request',
        'Server is not able to produce a response')
    UNPROCESSABLE_ENTITY = 422, 'Unprocessable Entity'
    LOCKED = 423, 'Locked'
    FAILED_DEPENDENCY = 424, 'Failed Dependency'
    TOO_EARLY = 425, 'Too Early'
    UPGRADE_REQUIRED = 426, 'Upgrade Required'
    PRECONDITION_REQUIRED = (428, 'Precondition Required',
        'The origin server requires the request to be conditional')
    TOO_MANY_REQUESTS = (429, 'Too Many Requests',
        'The user has sent too many requests in '
        'a given amount of time ("rate limiting")')
    REQUEST_HEADER_FIELDS_TOO_LARGE = (431,
        'Request Header Fields Too Large',
        'The server is unwilling to process the request because its header '
        'fields are too large')
    UNAVAILABLE_FOR_LEGAL_REASONS = (451,
        'Unavailable For Legal Reasons',
        'The server is denying access to the '
        'resource as a consequence of a legal demand')

    # server errors
    INTERNAL_SERVER_ERROR = (500, 'Internal Server Error',
        'Server got itself in trouble')
    NOT_IMPLEMENTED = (501, 'Not Implemented',
        'Server does not support this operation')
    BAD_GATEWAY = (502, 'Bad Gateway',
        'Invalid responses from another server/proxy')
    SERVICE_UNAVAILABLE = (503, 'Service Unavailable',
        'The server cannot process the request due to a high load')
    GATEWAY_TIMEOUT = (504, 'Gateway Timeout',
        'The gateway server did not receive a timely response')
    HTTP_VERSION_NOT_SUPPORTED = (505, 'HTTP Version Not Supported',
        'Cannot fulfill request')
    VARIANT_ALSO_NEGOTIATES = 506, 'Variant Also Negotiates'
    INSUFFICIENT_STORAGE = 507, 'Insufficient Storage'
    LOOP_DETECTED = 508, 'Loop Detected'
    NOT_EXTENDED = 510, 'Not Extended'
    NETWORK_AUTHENTICATION_REQUIRED = (511,
        'Network Authentication Required',
        'The client needs to authenticate to gain network access')

定义了一个名为 HTTPStatus 的 Python 类,该类继承自 IntEnum,这是 Python 内置 enum 模块中的一个子类,用于创建具有整数值的枚举类型。这个特定的 HTTPStatus 类是为了表示 HTTP 协议中的所有状态码及其相关的描述(原因短语)和详细说明。

通过这种方式组织,开发人员可以轻松地在他们的 HTTP 相关代码中使用这些枚举值,增加代码的可读性和安全性,因为这样可以防止由于手动输入状态码数字导致的错误,并且 IDE 和静态分析工具也能更好地识别和提示这些状态码。

2、示例

from your_module import HTTPStatus

# 创建一个 HTTPStatus 的实例
status = HTTPStatus.OK

# 访问状态码数值
print(status.value)  # 输出:200

# 访问原因短语
print(status.phrase)  # 输出:"OK"

# 访问详细描述
print(status.description)  # 输出:"Request fulfilled, document follows"

# 也可以通过名字获取状态码
status = HTTPStatus.NOT_FOUND

# 输出状态码及其相关信息
print(status.name, status.value, status.phrase, status.description)
# 输出:"NOT_FOUND 404 Not Found Nothing matches the given URI"

3、核心代码解析

def __new__(cls, value, phrase, description=''):
        obj = int.__new__(cls, value)
        obj._value_ = value

        obj.phrase = phrase
        obj.description = description
        return obj

在这段代码中,__new__ 是 Python 中的一个特殊方法,它是类实例化过程中的一个重要步骤。在这里,__new__ 方法被重写以定制 HTTPStatus 类实例的创建过程。

__new__ 方法接收四个参数:cls(当前类)、value(HTTP 状态码的整数值)、phrase(对应状态码的原因短语)和 description(状态码的详细描述,默认为空字符串)。

  1. int.__new__(cls, value):调用 int 类的 __new__ 方法来创建一个新的实例,但是返回的对象类型是 HTTPStatus 类而非 int 类。这意味着我们创建的是一个整数类型的 HTTPStatus 子类实例。

  2. obj._value_ = value:设置 _value_ 属性,这是 Enum 类要求的特殊属性,用于存储枚举成员的实际值。在这里就是给每个 HTTP 状态码分配其对应的数值。

  3. obj.phrase = phraseobj.description = description:分别给新创建的枚举成员对象添加两个自定义属性,即 phrasedescription,分别存储状态码的原因短语和详细描述。

  4. return obj:最后返回创建好的带有附加属性的 HTTPStatus 实例。

通过这样的设计,每次创建 HTTPStatus 类的一个状态码实例时,都会同时携带状态码数值、原因短语和描述信息,增强了对 HTTP 状态码的表达能力,使其更具可读性和实用性。

3.1、__all__ = [‘HTTPStatus’] 含义?

在Python中,__all__ 是一个特殊变量,它用于控制模块内哪些名称会被 import * 语句所导入。当你在一个模块中定义了 __all__ 列表,这个列表中的条目包含了你希望对外部世界暴露的所有公共API元素,如函数、类或变量。

3.2、int.new(cls, value) 换成 int(value) 不行吗?

HTTPStatus这个例子中,继承自IntEnum的类使用__new__方法来创建具有特殊属性(例如phrasedescription)的枚举成员。这里的目的是确保创建的每个枚举成员都是一个整数,同时带有额外的信息。

当写成 obj = int.__new__(cls, value) 时,它是在调用父类int__new__方法来创建一个实际的整数实例,并将其与当前类(即HTTPStatus)关联起来。这是正确的方式来构造一个同时作为整数并具有枚举特性的对象。

如果简单地替换为 obj = int(value),那么这将仅仅创建一个普通的int对象,而不是HTTPStatus类的一个实例。这样做的结果是丢失了枚举所特有的功能,比如可以通过名称访问成员以及保持附加属性的能力。

因此,在定义HTTPStatus这样的枚举类时,必须按照其__new__方法所示的方式调用基类int__new__方法,这样才能确保生成的对象既是int类型,又是HTTPStatus枚举类的实例。

3.3、为什么是obj._value_ = value 而不是obj.value = value

在Python的enum模块中,枚举成员有一个特殊属性_value_,它是用来存储枚举成员的实际值。将value赋给obj._value_的原因在于,enum.Enum会在内部处理 _value_ 属性来正确初始化枚举成员。

当你通过__new__方法创建一个枚举成员时,_value_属性被用来标识该枚举成员的具体数值,而不仅仅是任何其他自定义属性。在枚举中,_value_是用于区分不同枚举成员的关键属性,且在比较枚举成员时会直接参考这个值。

如果简单地设置obj.value = value,虽然可以给枚举成员添加一个名为value的属性,但它不会被enum模块识别为枚举成员的实际值。为了确保枚举的行为符合预期,必须使用_value_这一特殊属性来存储基础值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值