神技巧,在Python类初始化时进行四种暗箱操作

Python 构造方法 在Python中,构造方法的名称为__init__,它以self作为第一个参数,self代表类的实例,可以通过self来访问对象的属性和方法。当创建对象时,Python会自动调用构造方法,并传入相应的参数来初始化对象的属性。需要注意的是,在Python中,构造方法不是必需的。在上述例子中,Person类有一个构造方法__init__,它接收两个参数name和age,并通过self将它们赋值给对象的属性。构造方法以self作为第一个参数,self代表类的实例,可以通过self来访问对象的属性和方法。 阅读详情

Python 的类中,所有以双下划线__包起来的方法,叫魔术方法,魔术方法在类或对象的某些事件发出后可以自动执行,让类具有神奇的魔力,比如常见的构造方法__new、初始化方法init、析构方法del,今天来聊一聊new__的妙用,主要分享以下几点:

  • new 和 init 的区别
  • 应用1:改变内置的不可变类型
  • 应用2:实现一个单例
  • 应用3:客户端缓存
  • 应用4:不同文件不同的解密方法
  • 应用5:Metaclasses

new 和 init 的区别

1、调用时机不同:new 是真正创建实例的方法,init 用于实例的初始化,new 先于 init 运行。

2、返回值不同,new 返回一个类的实例,而 init 不返回任何信息。

3、new 是 class 的方法,而 init 是对象的方法。

示例代码:

class A:
    def __new__(cls, *args, **kwargs):
        print("new", cls, args, kwargs)
        return super().__new__(cls)

    def __init__(self, *args, **kwargs):
        print("init", self, args, kwargs)


def how_object_construction_works():
    x = A(1, 2, 3, x=4)
    print(x)    
    print("===================")
    x = A.__new__(A, 1, 2, 3, x=4)
    if isinstance(x, A):
        type(x).__init__(x, 1, 2, 3, x=4)
    print(x)

if __name__ == "__main__":
    how_object_construction_works()

上述代码定义了一个类 A,在调用 A(1, 2, 3, x=4) 时先执行 new,再执行 init,等价于:

x = A.__new__(A, 1, 2, 3, x=4)
if isinstance(x, A):
    type(x).__init__(x, 1, 2, 3, x=4)

代码的运行结果如下:

new <class '__main__.A'> (1, 2, 3) {'x': 4}
init <__main__.A object at 0x7fccaec97610> (1, 2, 3) {'x': 4}
<__main__.A object at 0x7fccaec97610>
===================
new <class '__main__.A'> (1, 2, 3) {'x': 4}
init <__main__.A object at 0x7fccaec97310> (1, 2, 3) {'x': 4}
<__main__.A object at 0x7fccaec97310>

new 的主要作用就是让程序员可以自定义类的创建行为,以下是Python 的构造方法 new 的常用场景:

应用1:改变内置的不可变类型

我们知道,元组是不可变类型,但是我们继承 tuple ,然后可以在 new 中,对其元组的元素进行修改,因为 new 返回之前,元组还不是元组,这在 init 函数中是无法实现的。比如说,实现一个大写的元组,代码如下:

class UppercaseTuple(tuple):
    def __new__(cls, iterable):
        upper_iterable = (s.upper() for s in iterable)
        return super().__new__(cls, upper_iterable)

    # 以下代码会报错,初始化时是无法修改的
    # def __init__(self, iterable):
    #     print(f'init {iterable}')
    #     for i, arg in enumerate(iterable):
    #         self[i] = arg.upper()

if __name__ == '__main__':
    print("UPPERCASE TUPLE EXAMPLE")
    print(UppercaseTuple(["hello", "world"]))

# UPPERCASE TUPLE EXAMPLE
# ('HELLO', 'WORLD')

应用2:实现一个单例

class Singleton:
    _instance = None

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super().__new__(cls, *args, **kwargs)
        return cls._instance


if __name__ == "__main__":

    print("SINGLETON EXAMPLE")
    x = Singleton()
    y = Singleton()
    print(f"{x is y=}")
# SINGLETON EXAMPLE
# x is y=True

应用3:客户端缓存

当客户端的创建成本比较高时,比如读取文件或者数据库,可以采用以下方法,同一个客户端属于同一个实例,节省创建对象的成本,这本质就是多例模式。

class Client:
    _loaded = {}
    _db_file = "file.db"

    def __new__(cls, client_id):
        if (client := cls._loaded.get(client_id)) is not None:
            print(f"returning existing client {client_id} from cache")
            return client
        client = super().__new__(cls)
        cls._loaded[client_id] = client
        client._init_from_file(client_id, cls._db_file)
        return client

    def _init_from_file(self, client_id, file):
        # lookup client in file and read properties
        print(f"reading client {client_id} data from file, db, etc.")
        name = ...
        email = ...
        self.name = name
        self.email = email
        self.id = client_id


if __name__ == '__main__':
    print("CLIENT CACHE EXAMPLE")
    x = Client(0)
    y = Client(0)
    print(f"{x is y=}")
    z = Client(1)
# CLIENT CACHE EXAMPLE
# reading client 0 data from file, db, etc.
# returning existing client 0 from cache
# x is y=True
# reading client 1 data from file, db, etc.

应用4:不同文件不同的解密方法

先在脚本所在目录创建三个文件:plaintext_hello.txt、rot13_hello.txt、otp_hello.txt,程序会根据不同的文件选择不同的解密算法

import codecs
import itertools


class EncryptedFile:
    _registry = {}  # 'rot13' -> ROT13Text

    def __init_subclass__(cls, prefix, **kwargs):
        super().__init_subclass__(**kwargs)
        cls._registry[prefix] = cls

    def __new__(cls, path: str, key=None):
        prefix, sep, suffix = path.partition(":///")
        if sep:
            file = suffix
        else:
            file = prefix
            prefix = "file"
        subclass = cls._registry[prefix]
        obj = object.__new__(subclass)
        obj.file = file
        obj.key = key
        return obj

    def read(self) -> str:
        raise NotImplementedError


class Plaintext(EncryptedFile, prefix="file"):
    def read(self):
        with open(self.file, "r") as f:
            return f.read()


class ROT13Text(EncryptedFile, prefix="rot13"):
    def read(self):
        with open(self.file, "r") as f:
            text = f.read()
        return codecs.decode(text, "rot_13")


class OneTimePadXorText(EncryptedFile, prefix="otp"):
    def __init__(self, path, key):
        if isinstance(self.key, str):
            self.key = self.key.encode()

    def xor_bytes_with_key(self, b: bytes) -> bytes:
        return bytes(b1 ^ b2 for b1, b2 in zip(b, itertools.cycle(self.key)))

    def read(self):
        with open(self.file, "rb") as f:
            btext = f.read()
        text = self.xor_bytes_with_key(btext).decode()
        return text


if __name__ == "__main__":
    print("ENCRYPTED FILE EXAMPLE")
    print(EncryptedFile("plaintext_hello.txt").read())
    print(EncryptedFile("rot13:///rot13_hello.txt").read())
    print(EncryptedFile("otp:///otp_hello.txt", key="1234").read())
# ENCRYPTED FILE EXAMPLE
# plaintext_hello.txt
# ebg13_uryyb.gkg
# ^FCkYW_X^GL

推荐阅读:

睡在我上铺的室友用python,一个月挣了我一学期的生活费

python之类的构造方法   Python 是一门易于学习、功能强大的编程语言。它提供了高效的高级数据结构,还能简单有效地面向对象编程。Python 优雅的语法和动态类型以及解释型语言的本质,使它成为多数平台上写脚本和快速开发应用的理想语言。下面我们来介绍一下python的类的构造方法。  构造方法的固定名称为__init__(),当创建类的对象时,系统会自动调用构造方法,从而实现对对象进行初始化的操作。   结果如下。   结果如下。   以上就是就是关于Python的类的构造方法相关知识,可以参考一下,觉得不错的话,欢迎点赞、 阅读详情

相关推荐

Python中的__new__方法:构造方法与作用

_new__方法可以看作是对象创建的第一步,它创建了实例并将其传递给__init__方法进行初始化。虽然在Python中没有严格的构造函数的概念,但是__new__方法可以看作是对象创建的第一步,它创建了一个实例,并将这个实例传递给__init__方法进行初始化。而在Python中,__new__方法负责创建对象,而__init__方法负责对象的初始化。__new__方法可以接受一些参数,用于传递给类的构造函数(__init__方法),以便进行进一步的初始化。方法中,我们打印了一条信息,并使用。

AlianBlank的博客 290

Python 中类的构造方法 __new__ 的妙用

Python 的类中,所有以双下划线__包起来的方法,叫魔术方法,魔术方法在类或对象的某些事件发出后可以自动执行,让类具有神奇的魔力,比如常见的构造方法__new__、初始化方法__ini...

somenzz的博客 841

Python异步类大揭秘:如何在初始化时顺利调用异步方法?

Python异步类大揭秘:如何在初始化时顺利调用异步方法?

XiaoqiangClub的博客 491

python init new class

#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2020/12/11 23:36 # @Author : flyx # @Site : # @File : newinit.py # @Software: PyCharm class Person(object): def __new__(cls,*args,**kwargs): print('__new__被调用执行了,cls的id为{0}'.f.

fly 541

【Python进阶】7个Python类技巧,你学会了吗?

类是面向对象编程中的基本构造块,它定义了一组具有相同属性和方法的对象。类可以看作是一个模板,用于创建具有相同特性的多个对象。Python中的类通过class关键字定义。定义一个类并创建类的实例是最基础的操作。class Dog:print(f"") # 创建类的实例 my_dog = Dog("Buddy" , 3) # 调用实例方法 my_dog . bark() # 输出: Buddy says woof!

java专栏 1106

linux上使用tun/tap设备模拟一个虚拟网卡,并将该虚拟网卡连接到新创建的网桥上

tun/tap设备是操作系统内核中的虚拟网络设备,是用软件模拟的网络设备,提供与硬件网络设备完全相同的功能。主要用于用户空间和内核空间传递报文。tun/tap对于硬件网络设备而言,一端连接的是物理网络,一端连接的是网络协议栈。对于tun/tap设备而言,一端连接的是应用程序(通过 字符设备文件),一端连接的是网络协议栈。

糖果墙的博客 6411

神技巧!在Python类初始化时进行四种暗箱操作!

Python 的类中,所有以双下划线__包起来的方法,叫魔术方法,魔术方法在类或对象的某些事件发出后可以自动执行,让类具有神奇的魔力,比如常见的构造方法__new__、初始化方法__ini...

cainiao_python的博客 358

Android 的端智能学习路径

基础层:先补齐 Android 进阶(JNI / 性能优化)和 AI 基础概念,无需深入算法开发;核心层:掌握 TFLite 的模型加载、推理、量化,能完成基础端侧推理;落地层:聚焦实战场景(图像 / OCR / 语音),解决工程化问题(模型管理、异常处理);优化层:通过模型量化、硬件加速、工程优化,提升推理性能和用户体验。

hqiangtai的博客 340

Python小技巧之——基类初始化

子类__init__初始化时,如果要对基类进行初始化,大家都知道可以用super:>>> class base(object): def __init__(self): print('base init') >>> class derived(base): def __init__(self): print('derived init') super(derived, se

wifeisboss的博客 4603

S/4HANA Private Cloud 与 On-Premise 的 Key User Custom Fields 运输与升级避坑指南

本文探讨了SAP S/4HANA Cloud Private Edition和On-Premise系统中Key User Custom Fields的管理要点。文章指出,Custom Fields涉及元数据生成、对象一致性、传输治理等完整链路,操作不当会导致字段丢失或升级失败。关键建议包括:使用ATO Fiori App管理扩展项与传输绑定,配置正确的job user权限,避免在多系统并行开发同一字段。特别强调升级时需执行CFD_REGENERATE_IN_ONPREMISE报表,并通过标准传输机制推进变更

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 195

【YOLOv8科研级优化】基于YOLOv9的GELAN模块重构C2f结构,实现精度与效率的同步提升

打开确保模型解析器能识别GELANBlock模块。通过将YOLOv9的GELAN模块集成到YOLOv8的C2f模块中,我们实现了一个“强特征表达+高效计算”的目标检测模型。这个改进不仅在工程上能提升复杂场景下的检测效果,更在科研上提供了“多分支特征融合”的创新思路——这种思路可以延伸到其他检测网络(如Faster R-CNN、SSD)的改进中,帮你在论文中打造独特的研究点。

know_F0727的博客 201

python 类初始化赋值,Python的类初始化方法

摘自Mastering Object-oriented Python隐式的基类——objectPython是面向对象程序设计语言,有一个类似root的基础类object类。任何自定义的类,都会隐式继承object。class X:passprint(X.__class__)# print(X.__class__.__base__)# 基类中的初始化方法延迟赋值这是指先创建类模板,然后在实例中定义属...

weixin_39622568的博客 2040

内部函数方式获取工序包容盒(最低点和最高点)PTHDSP_ask_box

内部函数方式获取工序包容盒(最低点和最高点)PTHDSP_ask_box。

成长需要沉淀。 397

【Python】【技能树评测】技巧实例-说明改进和实践【02】 - 类的初始化和初始化参数

本章,继续对优快云技能树的一些例子进行了改进说明和实践。希望能帮助在技能树游泳的哥们。原来的例子,写的注解太少了,没用的基本概念解释太多,花了时间看的,反而困惑了。再加上调用了choice这个随机取值函数,搞的结果更加玄乎,这个是一个培训的文案例子,建议修正。 上述代码,创建了一个Divergence的类, 其中,定义了一个类的初始化,这里除了,self参数外,还定义了,name的参数,同时他的默认初始值为‘robot’。定义了一个类的方法,该方法从内部的列表里面,随机取一个值输出,也就是实现了猜拳的功能

山云的专栏 420

[VT虚拟化驱动]利用EPT实现无痕HOOK

本章利用讲EPT无痕HOOK

吾无法无天的博客 1万+

PCL实现STL文件读取和转换为PCD格式

本文介绍如何使用点云库(Point Cloud Library,PCL)读取STL(Standard Triangle Language)文件,并将其转换为点云数据(PointCloud Data,PCD)格式。通过将STL文件转换为PCD格式,我们可以更方便地处理和分析点云数据。本文介绍了如何使用PCL库读取STL文件并将其转换为PCD格式的点云数据。以上是关于PCL读取STL文件并转存为PCD格式的简要介绍和示例源代码。下面的示例展示了如何将STL文件转换为PCD格式。函数将点云数据保存为PCD文件。

ByteEchoX的博客 804

Python 类的10个技巧,让你轻松写出优雅代码

朋友,你好!在Python编程中,类(Class)是面向对象编程(OOP)的核心概念之一。掌握类的使用,不仅能让你的代码更加结构化,还能提高代码的可读性和可维护性。

公众号【伤心的辣条】资料领取~ 1121

RK3568平台开发系列讲解(中断及异常篇)中断下半部:中断线程化

以前用 work 来线程化地处理中断,一个 worker 线程只能由一个 CPU 执行, 多个中断的 work 都由同一个 worker 线程来处理,在单 CPU 系统中也只能忍着 了。少数中断不能线程化,典型的例子是时钟中断,有些流氓进程不主动让出处理器,内核只能依靠周期性的时钟中断夺回处理器的控制权,时钟中断是调度器的脉搏。中断处理线程是优先级为50、调度策略是SCHED_FIFO的实时内核线程,名称是“irq/”后面跟着Linux中断号,线程处理函数是。,说明是线程化的中断,那么唤醒中断处理线程。

内核笔记 435

python参数初始化_python参数初始化

python 初始化参数怎么设置class A(object): def __init__(arg): self.arg = arg 在__init__中定义python中类的初始化函数形参=0含义看来你是学c#不久的 private和public作为访问权限来 控制变量的作用域是很有必要的 这直接关系到了变量被访问的方式和范围 还有你说的那个不是等价的 虽然从赋值的效果是一样的 然而如果 你要从...

weixin_30224231的博客 3917

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Python 拆分Word文档的四种实用技巧

这篇文章介绍了使用Python拆分Word文档的四种方式,包含详细的步骤介绍和代码示例。

nuclear2011的博客 3328

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

关于牛客笔试时初始化输入(python链表初始化和列表初始化)

1.只有一个整数:a = int(input) 2.一行多个整数并用空格分开:a,b = map(int,input().split()) 3.数据较多时可用 列表存储:num = list(map(int,input().split())) 4.关于初始化链表: class Node: def __init__(self,x): self.val = x ...

sinat_35325378的博客 1137

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Python list接收返回值时无需初始化

我们知道python中list在使用时应当提前先进行初始化,否则将会报错,代码如下: class Debug: def mainProgram(self): list1 = [2, 3] for i in list1: list2.append(i) if __name__ == "__main__": main =Debug() main.mainProgram() """ name 'list2' is

u011699626的博客 649

python 基类初始化_如何初始化基类(超级类)?

How do I initialize the base (super) class?class SuperClass(object):def __init__(self, x):self.x = xclass SubClass(SuperClass):def __init__(self, y):self.y = y使用一个super对象来确保获得方法解析顺序中的下一个方法(作为绑定方法)。在Py...

weixin_28932617的博客 835

在定义的时候初始化类成员:Python类设计的最佳实践

在定义的时候初始化类成员:Python类设计的最佳实践

KE17RS的博客 1068

python编程书写技巧_Python 内编写类的各种技巧和方法

Python 内编写类的各种技巧和方法简介有关 Python 内编写类的各种技巧和方法(构建和初始化、重载操作符、类描述、属性访问控制、自定义序列、反射机制、可调用对象、上下文管理、构建描述符对象、Pickling)。 你可以把它当作一个教程,进阶,或者使用参考;我希望它能够成为一份针对 Python 方法的用户友好指南。本文源码托管在 github 上:https://github.com/ju...

weixin_39657575的博客 189

Python 内编写类的各种技巧和方法

简介 有关 Python 内编写类的各种技巧和方法(构建和初始化、重载操作符、类描述、属性访问控制、自定义序列、反射机制、可调用对象、上下文管理、构建描述符对象、Pickling)。 你可以把它当作一个教程,进阶,或者使用参考;我希望它能够成为一份针对 Python 方法的用户友好指南。 内容目录 介绍 构建和初始化 使操作符在自定义类内工作 神奇方法——比较 神奇方法——数字 描述你的类 属性访...

Python热爱者的博客 584
上一篇: 阿里美国员工薪资曝光,工程师底薪最高超20万美元
下一篇: 用 python 制作高逼格的数学动画
Python_金钱豹
博客等级 码龄5年 1万+粉丝 2826原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值