python魔法方法
在学习面向对象的时候,我们知道在 python 中有一类特殊的方法,叫做魔法方法,这种方法的特点如下:
- 方法定义的时候以两个下划线开头和两个下划线结尾:如
__init__
、__str__
和__repr__
- 这类方法一般不需要我们手动调用,在满足某个条件的时候会自动调用,这个满足的条件我们可以成为调用时机
__str__()
方法
这个类方法(str())主要的作用是在print(实例)的时候返回你指定的字符串,一般来说在定义类的时候不用重写这个方法的,但是在一些注重交互的模块类的编写上,可能会重写这个类。下面直接进入例子。
class Car(): def __init__(self,name): self.name = name
接下来我们实例化这个类,并打印这个实例。
A = Car('BNW') print(A)
我们一般就能看到这样的结果:
<__main__.Car object at 0x000002B249DD4E20>
这个结果主要是告诉我们这个A是哪一个类(Car类),还有所在内存位置(0x000002B249DD4E20)
下面我们在Car类中重写__str__方法,再打印这个A,看看会有什么差别。
class Car(): def __init__(self, name): self.name = name def __str__(self) -> str: text = f'这是一辆车,名字是{self.name}' return text A = Car('BNW') print(A)
这是一辆车,名字是BNW
可以看到,这个时候print(实例),将会出现我们指定好的str内容。这就是__str__()方法的用处,不过要注意,这个方法必须要保证返回的是一个str。
对一个对象打印时,自动执行 str 方法
class A: def __init__(self, name, age): self.name = name self.age = age self.sex = "男" def __str__(self): print(555) return "abc" a1 = A("尘世风", 18) # 对一个对象打印时,自动执行 __str__ 方法 print(a1) # 运行结果: # 555 # abc
__len__()
方法
len()可以检测对象中某个数据得信息,只有一个参数self,用于接收当前对象,它必须有返回值,返回值必须是整数;
当我们不使用__len__()方法检测对象时,会报TypeError: object of type ‘UseLen’ has no len()错误
class UseLen(object): def __init__(self, age): self.age = age self.li = ['a', 'v', 's'] U = UseLen(12) print(len(U))
Traceback (most recent call last): File "D:\code\xmczapitest\test.py", line 7, in <module> print(len(U)) TypeError: object of type 'UseLen' has no len()
当我们使用__len__方法检测对象时,需要注意的是必须有返回值,方法中只有一个self参数
class UseLen(object): def __init__(self, age): self.age = age self.li = ['a', 'v', 's'] def __len__(self): return len(self.__dict__) U = UseLen(12) print(len(U)) # 2
__call__
方法
__call__可以使得方法变成可被调用对象
class Foo: def __init__(self): print("实例化一个对象时自动执行 __init__ 方法") def __call__(self, *args, **kwargs): print('调用实例化对象时自动触发 __call__ 方法') obj = Foo() # 实例化一个对象时自动执行 __init__ 方法 obj() # 调用实例化对象时自动触发 __call__ 方法
new() 方法
当Python实例化一个对象时,首先调用__new__()方法构造一个类的实例,并为其分配对应类型的内存空间,该实例的内存地址就是它的唯一标识符。然后再调用__init__()方法对实例进行初始化,通常是对该实例的属性进行初始化
以下用几个实例来说明:
实例1:先调用__new__()方法再调用__init__()方法
class Person(object): def __new__(cls): print("__new__ called") return super().__new__(cls) def __init__(self): print("__init__ called") a = Person()
结果
__new__ called __init__ called
实例2:new()方法构造一个类实例,并将该实例传递给自身的__init__()方法,即__init__()方法的self参数。
class Person(object): def __new__(cls): print("__new__ called") instance = super().__new__(cls) print(type(instance)) print(instance) print(id(instance)) return instance def __init__(self): print("__init__ called") print(id(self)) b = Person()
结果
__new__ called <class '__main__.Person'> <__main__.Person object at 0x0000026D76844DC0> 2669163072960 __init__ called 2669163072960
实例3:如果__new__()方法不返回任何实例的话,init()方法将不会被调用。
class Person(object): def __new__(cls): print("__new__ called") def __init__(self): print("__init__ called") c = Person()
结果:
__new__ called
实例4:如果__new__()方法返回一个其他类的实例的话,那它自身的__init__()方法将不会被调用。而且,new()方法将会初始化一个其他类的对象。
class Animal(object): def __init__(self): pass class Person(object): def __new__(cls): print("__new__ called") return Animal() def __init__(self): print("__init__ called") d = Person() print(type(d)) print(d)
结果:
__new__ called <class '__main__.Animal'> <__main__.Animal object at 0x0000022BDDEEF400>
实例5:如果重写__new__()方法时,除了cls参数外不再设置其他参数的话,将无法用__init__()方法来设置初始化参数。
class Person(object): def __new__(cls): print("__new__ called") instance = super().__new__(cls) return instance def __init__(self, name): print("__init__ called") self.name = name e = Person("Alice") print(e.name) # TypeError: Person.__new__() takes 1 positional argument but 2 were given
实例6:在重写__new__()方法时,需要在参数中加入*args,**kwargs,或者显式地加入对应的参数,才能通过__init__()方法初始化参数。
class Person(object): def __new__(cls, *args,**kwargs): # Or def __new__(cls, name) print("__new__ called") instance = super().__new__(cls) return instance def __init__(self, name): print("__init__ called") self.name = name e = Person("Alice") print(e.name)
结果:
__new__ called __init__ called Alice
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现