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
用途
-
工厂模式:
__call__
方法常用于实现工厂模式,其中类的实例负责创建其他对象。 -
装饰器:在装饰器模式中,
__call__
方法用于包装函数或方法,以添加额外的功能。 -
回调函数:在需要回调函数的场景中,
__call__
方法允许类的实例作为回调函数。 -
单例模式:
__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]