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

Python学习第十五天--魔术方法

魔法方法就是可以给你的类增加魔力的特殊方法,它们总被双下划线所包围,像这种格式:"__方法名__",这些方法很强大,充满魔力,可以让你实现很多功能。

使用dir()查看类的所有属性和方法

class A:
    pass

print(dir(A))

"""
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
"""

一、__doc__

表示类的描述信息,它通常被放置在类定义的第一行,并且被三引号(""")包围。print(A.__doc__)打印出来的是其中的信息

class A:
    """hello world"""
    def hello(self):
        print("Hello")

print(A.__doc__)

>>> hello world

二、__module__(读取使用的模块名)

返回定义该类的原始模块名

例如:如果一个类定义在名为my_module.py的文件中,那么这个类的__module__属性将会返回字符串'my_module'。这表明类是在这个模块中定义的。

三、__class__(读取使用的类名)

返回对象的类

class MyClass:
    pass

# 创建MyClass的一个实例
my_instance = MyClass()

# 访问实例的__class__属性
print(my_instance.__class__)  # 输出: <class '__main__.MyClass'>

四、__call__

允许一个类的实例像函数一样被调用。在类中定义__call__方法。这个方法接受任意数量的参数,这些参数在实例被调用时传递给__call__方法。

class Calculator:
    def __init__(self, initial_value=0):
        self.value = initial_value

    def __call__(self, *args, **kwargs):
        # 这里可以根据需要处理 *args 和 **kwargs
        # 例如,我们可以将所有的位置参数累加到 self.value
        for arg in args:
            self.value += arg
        # 处理关键字参数,例如,如果有一个关键字参数 'multiply'
        if 'multiply' in kwargs:
            self.value *= kwargs['multiply']
        return self.value

# 法一:
# 创建Calculator类的实例
calc = Calculator(10)

# 调用实例,传递任意数量的位置参数和关键字参数
result = calc(5, 3, multiply=2)  # 10 + 5 + 3 = 18, then multiply by 2

#法二:
result = Calculator(10)(5, 3, multiply=2)

print(result)  # 输出: 36

用途

  1. 工厂模式__call__方法常用于实现工厂模式,其中类的实例负责创建其他对象。

  2. 装饰器:在装饰器模式中,__call__方法用于包装函数或方法,以添加额外的功能。

  3. 回调函数:在需要回调函数的场景中,__call__方法允许类的实例作为回调函数。

  4. 单例模式__call__方法也可以用于实现单例模式,确保只创建类的单个实例。

五、__dict__

它是一个字典,包含了类或对象的所有属性和它们的值,这些属性是动态添加到实例上的,并且不是在类定义时就确定的。

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

print(Person.__dict__)  # 输出: {'__module__': '__main__', '__init__': <function Person.__init__ at 0x0000022AFDF5D1F0>, 
# '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}

# 创建Person类的实例
person = Person("Alice", 30)

# 访问实例的__dict__属性
print(person.__dict__)  # 输出: {'name': 'Alice', 'age': 30}

# 向实例添加新属性
person.gender = "Female"

# 查看添加新属性后的__dict__
print(person.__dict__)  # 输出: {'name': 'Alice', 'age': 30, 'gender': 'Female'}

dir():

  • dir() 返回一个包含对象的所有属性和方法的列表,包括那些继承自父类的属性和方法。
  • 它不仅包括实例属性,还包括类属性、内置属性和方法。

__dict__:

  • __dict__ 只包含一个对象的实例属性,即那些在对象创建后添加到对象中的属性。
  • 它不包括类属性或者继承自父类的属性和方法。
  • __dict__ 是一个字典对象,其中包含了实例属性的名称和值。

综上__dict__ 是 dir() 的子集

六、__repr__

 改变对象的字符串显示

__str__():打印实例对象时,返国自定义的字符串---输出是给用户看的

__repr__():输出是给程序员Dedbug看的

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f"Point({self.x}, {self.y})"

# 创建Point类的实例
p = Point(1, 2)

# 使用repr()函数或直接打印对象
print(repr(p))  # 输出: Point(1, 2)
print(p)        # 输出: Point(1, 2),因为__str__没有定义,所以打印时也调用了__repr__

七、__getitem____setitem____delitem__

允许对象模拟序列(如列表和元组)或映射(如字典)的行为。这些方法使得对象可以支持索引、切片和赋值操作。

class Sequence:
    def __init__(self, elements):
        self.elements = elements

    def __getitem__(self, index):
        return self.elements[index]

    def __setitem__(self, index, value):
        self.elements[index] = value

    def __delitem__(self, index):
        del self.elements[index]

# 创建Sequence类的实例
seq = Sequence([1, 2, 3, 4, 5])

# 使用__getitem__方法,会自动触发
print(seq[0])  # 输出: 1

# 使用__setitem__方法,会自动触发
seq[0] = 10
print(seq.elements)  # 输出: [10, 2, 3, 4, 5]

# 使用__delitem__方法,会自动触发
del seq[0]
print(seq.elements)  # 输出: [2, 3, 4, 5]


http://www.kler.cn/a/419801.html

相关文章:

  • Kong API Gateway 深度解析与实战指南
  • 【Linux内核】ashmem pin/unpin
  • Python毕业设计选题:基于django+vue的校园影院售票系统
  • CasaOS个人云存储系统使用Gopeed打造你的私人云端下载中心
  • Spring Boot自定义启动banner
  • 基于深度学习的甲状腺结节影像自动化诊断系统(PyQt5界面+数据集+训练代码)
  • 在 Ubuntu 使用 fonts-noto-cjk 设置 Matplotlib 支持中文的完整教程
  • Makefile 入门指南:构建自动化编译流程
  • java 反射 详解
  • Ubuntu 20.04 下 ROS 工作空间的详解与应用
  • rustdesk远程桌面使用
  • Milvus Cloud 2.5:易用性飞跃,助力用户高效管理向量数据库
  • 一款支持80+语言,包括:拉丁文、中文、阿拉伯文、梵文等开源OCR库
  • 【k8s深入学习之 event 记录】初步了解 k8s event 记录机制
  • 【ROS2】Ubuntu22.04安装ROS humble
  • 网络诊断指南:网络故障排查步骤与技巧
  • iOS——MVC、MVP、MVVM
  • leetcode——二分法
  • 4.22CACHE计算
  • 如何在centos7 安装vscode软件教程(图文教程)