内置方法
【一】常用方法
【二】代码详细
官方文档
【1】特殊方法(魔法方法)
1.__new__
| class Foo(object): |
| def __new__(cls, *args, **kwargs): |
| print("创建实例时被调用") |
| |
| |
| f = Foo() |
2.__init__
| class Foo(object): |
| def __init__(self, name,age): |
| self.name = name |
| self.age = age |
| print("初始化实例时被调用") |
| |
| |
| f = Foo('001',18) |
| print(f.__dict__) |
3.__del__
| '''实例被销毁时触发''' |
| class Foo(object): |
| def __init__(self, name, age): |
| self.name = name |
| self.age = age |
| |
| def __del__(self): |
| print("实例被销毁时触发") |
| |
| |
| f = Foo('001', 18) |
| del f |
| '''程序结束时触发''' |
| class Foo(object): |
| def __init__(self, name, age): |
| self.name = name |
| self.age = age |
| |
| def __del__(self): |
| print("程序结束时触发") |
| |
| |
| f = Foo('001', 18) |
| print("====程序即将结束====") |
| ''' |
| ====程序即将结束==== |
| 程序结束时触发 |
| ''' |

4.__call__
- 对象作为函数被”调用“时触发,如
对象+()
- 此方法会在实例作为一个函数被“调用”时被调用;如果定义了此方法,则
x(arg1, arg2, ...)
就大致可以被改写为 type(x).__call__(x, arg1, ...)
。
| class Foo(object): |
| def func(self): |
| print("func") |
| |
| def __call__(self, *args, **kwargs): |
| print("call") |
| |
| |
| f = Foo() |
| f() |
| class Foo(object): |
| def func(self): |
| print("func") |
| |
| def __call__(self, *args, **kwargs): |
| for i in args: |
| print(i, end='-') |
| |
| |
| |
| f = Foo() |
| f(1, 2, 3, 4) |
5.__str___
/__repr__
print()/str()/repr()
时触发,必须返回字符串
| '''__str__''' |
| class Foo(object): |
| def __str__(self): |
| print("print()时触发") |
| print("str()时触发") |
| return "必须要返回字符串" |
| |
| |
| |
| |
| f = Foo() |
| print(f) |
| res = str(f) |
| print(res) |
| |
| '''__repr__''' |
| '''除调用方式略有差别,其余一致,返回值同样需要是字符串''' |
| class Foo: |
| def __repr__(self): |
| print("print() / repr()时触发") |
| return "repr" |
| |
| |
| f = Foo() |
| print(f) |
| repr(f) |
| ''' |
| print() / repr()时触发 |
| repr |
| print() / repr()时触发 |
| ''' |
[5.1]__str__
优先级更高
| class Foo(object): |
| def __repr__(self): |
| print("repr") |
| return "print() / repr()时触发" |
| |
| def __str__(self): |
| print("str") |
| return "print() / str()时触发" |
| |
| |
| |
| |
| |
| |
| f = Foo() |
| print(f) |
| |
| |
| ''' |
| str |
| print() / str()时触发 |
| ''' |
[5.2] 调用方式不一致
| class Foo(object): |
| def __repr__(self): |
| print("repr") |
| return "print() / repr()时触发" |
| |
| |
| f = Foo() |
| str(f) |
| print(Foo()) |
- 当
__repr__
不存在时,不会自动调用__str__
| class Foo(object): |
| def __str__(self): |
| print("str") |
| return "print() / str()时触发" |
| |
| |
| f = Foo() |
| print(repr(f)) |
| |
print()
时,存在哪个调用哪个,如果都存在将只调用__str__
[5.3] __repr__
与__str__
的区别
【1】官方解释
-
object.__repr__(self)
- 由
repr()
内置函数调用以输出一个对象的“官方”字符串表示。如果可能,这应类似一个有效的 Python 表达式,能被用来重建具有相同取值的对象(只要有适当的环境)。如果这不可能,则应返回形式如 <...some useful description...>
的字符串。返回值必须是一个字符串对象。如果一个类定义了 __repr__()
但未定义 __str__()
,则在需要该类的实例的“非正式”字符串表示时也会使用 __repr__()
。此方法通常被用于调试,因此确保其表示的内容包含丰富信息且无歧义是很重要的。
-
object.__str__(self)
【2】使用datetime.date
展示区别
| import datetime |
| |
| today = datetime.datetime.today() |
| print(str(today)) |
| print(repr(today)) |
| print(today.__str__()) |
| print(today.__repr__()) |
__str__
的返回结果可读性强
__repr__
的返回结果应更准确。
6.__setattr__
/__delattr__
/__getattr__
和__getattribute__()
-
__getattr__(self, item)
: 访问不存在的属性时调用
-
__setattr__(self, key, value)
:设置实例对象的一个新的属性时调用
-
__delattr__(self, item)
:删除一个实例对象的属性时调用
| class Foo(object): |
| def __init__(self, name): |
| self.name = name |
| |
| def __getattr__(self, item): |
| print(f"访问不存在的属性时触发") |
| return f"{item}不存在" |
| |
| def __setattr__(self, key, value): |
| print("设置属性时触发") |
| |
| self.__dict__[key] = value |
| |
| def __delattr__(self, item): |
| print("删除属性时触发") |
| |
| self.__dict__.pop(item) |
| |
| |
| f = Foo('user') |
| print(f.__dict__) |
| print(f.sex) |
| ''' |
| 访问不存在的属性时触发 |
| sex不存在 |
| ''' |
| f.name = '001' |
| print(f.__dict__) |
| |
| del f.name |
| |
| print(f.__dict__) |
| '''我们可以自行定制,对应操作时的结果''' |
| class Foo(object): |
| def __init__(self, name): |
| self.__dict__['name'] = name |
| |
| def __getattr__(self, item): |
| |
| self.__dict__[item] = f'自动创建的{item}' |
| return self.__dict__[item] |
| |
| def __setattr__(self, key, value): |
| |
| self.__dict__[f"{key}_new"] = value |
| |
| def __delattr__(self, item): |
| |
| old_value = self.__dict__[item] |
| self.__dict__[f"{item}_del"] = old_value |
| |
| |
| f = Foo('user') |
| print(f.__dict__) |
| print(f.sex) |
| |
| f.name = '001' |
| print(f.__dict__) |
| |
| del f.name |
| |
| print(f.__dict__) |
| class Foo(object): |
| def __init__(self, name): |
| self.name = name |
| |
| def __getattr__(self, item): |
| print(f"访问不存在的属性时触发") |
| return f"{item}不存在" |
| |
| |
| def __getattribute__(self, item): |
| print("会无条件地被调用以实现对类实例属性的访问,不论是否存在") |
| return super().__getattribute__(item) |
| |
| |
| |
| |
| |
| f = Foo('user') |
| print(f.name) |
| print(f.sex) |
| ''' |
| print(f.name) >>> |
| 会无条件地被调用以实现对类实例属性的访问,不论是否存在 |
| user |
| print(f.sex) >>> |
| 会无条件地被调用以实现对类实例属性的访问,不论是否存在 |
| 访问不存在的属性时触发 |
| sex不存在 |
| ''' |
8.__setitem__
/__getitem__
/__delitem__
| class Foo(object): |
| def __init__(self, name, age): |
| self.name = name |
| self.age = age |
| |
| def __getitem__(self, item): |
| return self.__dict__[item] |
| |
| def __setitem__(self, key, value): |
| self.__dict__[key] = value |
| |
| def __delitem__(self, key): |
| self.__dict__.pop(key) |
| |
| |
| f = Foo('user', 18) |
| |
| |
| print(f['name']) |
| |
| f['name'] = 'learning' |
| print(f.__dict__) |
| |
| f['sex'] = 'male' |
| print(f.__dict__) |
| |
| del f['age'] |
| print(f.__dict__) |
| class Foo(object): |
| def __init__(self, name, age): |
| self.name = name |
| self.age = age |
| |
| def __getitem__(self, item): |
| return f'{item}保密' |
| |
| def __setitem__(self, key, value): |
| user_dict={key:value} |
| print(f"不准改!{user_dict}") |
| |
| def __delitem__(self, key): |
| print(f"不要删【{key}】~球球了~") |
| |
| |
| f = Foo('user', 18) |
| |
| |
| print(f['name']) |
| |
| f['name'] = 'learning' |
| |
| f['sex'] = 'male' |
| |
| del f['age'] |
9.__dir__
- 此方法会在对相应对象调用
dir()
时被调用。返回值必须为一个序列。 dir()
会把返回的序列转换为列表并对其排序。
| '''【->】表示函数的返回类型注解''' |
| class Foo(object): |
| def __dir__(self) -> [str]: |
| print("调用__dir__") |
| return ['a', 'b', 'c'] |
| |
| |
| f = Foo() |
| print(dir(f)) |
| class Foo(object): |
| def __dir__(self) -> [str]: |
| print("调用__dir__") |
| return super().__dir__() |
| |
| |
| f = Foo() |
| print(dir(f)) |
10.__enter__
/__exit__
-
上下文管理器 — Python 3.10.13 文档
-
with方法中的必须包含的方法
-
object.__enter__(self)
进入与此对象相关的运行时上下文。 with
语句将会绑定这个方法的返回值到 as
子句中指定的目标,如果有的话。
-
object.__exit__(self, exc_type, exc_value, traceback)
退出关联到此对象的运行时上下文。 各个参数描述了导致上下文退出的异常。 如果上下文是无异常地退出的,三个参数都将为 None
。如果提供了异常,并且希望方法屏蔽此异常(即避免其被传播),则应当返回真值。 否则的话,异常将在退出此方法时按正常流程处理。
[10.1] 代码演示
| '''简单演示''' |
| class Foo(object): |
| def __init__(self, filename): |
| self.name = filename |
| |
| def __enter__(self): |
| print("with语句一执行,就会执行enter中的代码") |
| |
| def __exit__(self, exc_type, exc_val, exc_tb): |
| print("with语句执行完毕,就会执行exit中的代码") |
| |
| |
| f_obj = Foo('b.txt') |
| with f_obj as fp: |
| print("执行with语句中的代码") |
| |
| |
| ''' |
| 输出: |
| with语句一执行,就会执行enter中的代码 |
| 执行with语句中的代码 |
| with语句执行完毕,就会执行exit中的代码 |
| ''' |
| |
| '''使用with时,必须保证enter和exit都有,否则将报错''' |
| class Foo(object): |
| def __enter__(self): |
| print("with语句一执行,就会执行enter中的代码") |
| |
| f_obj = Foo() |
| |
| with f_obj as fp: |
| print("执行with语句中的代码") |
| |
[10.2] 使用enter和exit实现 with文件操作
| '''使用enter和exit实现 with文件操作''' |
| class MyOpen(): |
| def __init__(self, filename, mode='r', encoding='utf8'): |
| self.file = open(file=filename, mode=mode, encoding=encoding) |
| |
| def __enter__(self): |
| print(type(self.file)) |
| return self.file |
| |
| def __exit__(self, exc_type, exc_val, exc_tb): |
| print("开始执行关闭文件语句喽~") |
| self.file.close() |
| |
| |
| file = MyOpen('b.txt') |
| with file as f: |
| print(type(file)) |
| data = f.read() |
| print(data) |
| |
[10.3] __exit__
参数介绍
[10.3.1] with语句中出现异常
| class Foo(object): |
| def __init__(self, filename): |
| self.name = filename |
| |
| def __enter__(self): |
| print("with语句一执行,就会执行enter中的代码") |
| |
| def __exit__(self, exc_type, exc_val, exc_tb): |
| print("with语句执行完毕,就会执行exit中的代码") |
| print(f"exc_type : {exc_type}") |
| print(f"exc_val : {exc_val}") |
| print(f"exc_tb : {exc_tb}") |
| |
| |
| f_obj = Foo('b.txt') |
| with f_obj as fp: |
| print("执行with语句中的代码") |
| raise AttributeError("手动创建的错误") |
| ''' |
| 输出: |
| with语句一执行,就会执行enter中的代码 |
| 执行with语句中的代码 |
| with语句执行完毕,就会执行exit中的代码 |
| exc_type : <class 'AttributeError'> |
| exc_val : 手动创建的错误 |
| exc_tb : <traceback object at 0x0000015A39DADE00> |
| ''' |
[10.3.2]with语句中无异常
| class Foo(object): |
| def __init__(self, filename): |
| self.name = filename |
| |
| def __enter__(self): |
| print("with语句一执行,就会执行enter中的代码") |
| |
| def __exit__(self, exc_type, exc_val, exc_tb): |
| print("with语句执行完毕,就会执行exit中的代码") |
| print(f"exc_type : {exc_type}") |
| print(f"exc_val : {exc_val}") |
| print(f"exc_tb : {exc_tb}") |
| |
| |
| f_obj = Foo('b.txt') |
| with f_obj as fp: |
| print("执行with语句中的代码") |
| |
| |
| ''' |
| 输出: |
| with语句一执行,就会执行enter中的代码 |
| 执行with语句中的代码 |
| with语句执行完毕,就会执行exit中的代码 |
| exc_type : None |
| exc_val : None |
| exc_tb : None |
| ''' |
[10.3.3]有异常,但是希望方法屏蔽此异常(即避免其被传播)
| class Foo(object): |
| def __init__(self, filename): |
| self.name = filename |
| |
| def __enter__(self): |
| print("with语句一执行,就会执行enter中的代码") |
| |
| def __exit__(self, exc_type, exc_val, exc_tb): |
| print("with语句执行完毕,就会执行exit中的代码") |
| print(f"exc_type : {exc_type}") |
| print(f"exc_val : {exc_val}") |
| print(f"exc_tb : {exc_tb}") |
| return True |
| |
| |
| f_obj = Foo('b.txt') |
| with f_obj as fp: |
| print("执行with语句中的代码") |
| raise AttributeError("手动创建的错误") |
| |
| ''' |
| 输出: |
| with语句一执行,就会执行enter中的代码 |
| 执行with语句中的代码 |
| with语句执行完毕,就会执行exit中的代码 |
| exc_type : <class 'AttributeError'> |
| exc_val : 手动创建的错误 |
| exc_tb : <traceback object at 0x000001A22D98DE00> |
| |
| Process finished with exit code 0 # 将不会中断程序,而是正常执行完毕 |
| ''' |
11.__gt__()
,__lt__()
,__eq__()
,__ne__()
,__ge__()
:“富比较”方法
- 富比较方法 — Python 3.10.13 文档
- 如果指定的参数对没有相应的实现,富比较方法可能会返回单例对象
NotImplemented
。按照惯例,成功的比较会返回 False
或 True
。不过实际上这些方法可以返回任意值,因此如果比较运算符是要用于布尔值判断(例如作为 if
语句的条件),Python 会对返回值调用 bool()
以确定结果为真还是假。
| class Foo: |
| def __init__(self, num): |
| self.num = num |
| |
| def __lt__(self, other): |
| '''x<y''' |
| return f" lt | x<y |{self.num < other.num}" |
| |
| def __le__(self, other): |
| '''x<=y''' |
| return f" le | x<=y |{self.num <= other.num}" |
| |
| def __eq__(self, other): |
| '''x == y''' |
| return f" eq | x==y |{self.num == other.num}" |
| |
| def __ne__(self, other): |
| '''x!=y''' |
| return f" ne | x!=y |{self.num != other.num}" |
| |
| def __gt__(self, other): |
| '''x>y''' |
| return f" gt | x>y |{self.num > other.num}" |
| |
| def __ge__(self, other): |
| '''x>=y''' |
| return f" ge | x>=y |{self.num >= other.num}" |
| |
| |
| a = Foo(10) |
| b = Foo(5) |
| |
| print(a < b) |
| print(a <= b) |
| print(a == b) |
| print(a != b) |
| print(a > b) |
| print(a >= b) |
| '''类似的数值运算方法''' |
| |
| class Point(object): |
| def __init__(self): |
| self.x = -1 |
| self.y = 5 |
| def __pos__(self): |
| pass |
| |
| def __neg__(self): |
| pass |
| |
| def __invert__(self): |
| pass |
| |
| def __abs__(self): |
| pass |
| |
| |
| def __add__(self, other): |
| pass |
| |
| def __sub__(self, other): |
| pass |
| |
| def __divmod__(self, other): |
| pass |
| |
| def __mul__(self, other): |
| pass |
| |
| def __mod__(self, other): |
| pass |
| |
| def __pow__(self, power, modulo=None): |
| pass |
| |
| |
| def __and__(self, other): |
| pass |
| |
| def __or__(self, other): |
| pass |
| |
| def __xor__(self, other): |
| pass |
| |
| |
| def __lshift__(self, other): |
| pass |
| |
| def __rshift__(self, other): |
| pass |
| |
| |
| def __iadd__(self, other): |
| pass |
| |
| def __imul__(self, other): |
| pass |
| |
| def __isub__(self, other): |
| pass |
| |
| def __idiv__(self, other): |
| pass |
| |
| def __imod__(self, other): |
| pass |
| |
| def __ipow__(self, other): |
| pass |
| |
| def __ilshift__(self, other): |
| pass |
| |
| def __irshift__(self, other): |
| pass |
【2】内置方法
属性 |
含意 |
|
__doc__ |
该函数的文档字符串,没有则为 None ;不会被子类继承。 |
可写 |
__name__ |
该函数的名称。 |
可写 |
__qualname__ |
该函数的 qualified name。3.3 新版功能. |
可写 |
__module__ |
该函数所属模块的名称,没有则为 None 。 |
可写 |
__defaults__ |
由具有默认值的参数的默认参数值组成的元组,如无任何参数具有默认值则为 None 。 |
可写 |
__code__ |
表示编译后的函数体的代码对象。 |
可写 |
__globals__ |
对存放该函数中全局变量的字典的引用 --- 函数所属模块的全局命名空间。 |
只读 |
__dict__ |
命名空间支持的函数属性。 |
可写 |
__closure__ |
None 或包含该函数可用变量的绑定的单元的元组。有关 cell_contents 属性的详情见下。 |
只读 |
__annotations__ |
包含形参标注的字典。 字典的键是形参名,而如果提供了 'return' 则是用于返回值标注。 有关如何使用此属性的更多信息,请参阅 对象注解属性的最佳实践。 |
可写 |
__kwdefaults__ |
仅包含关键字参数默认值的字典。 |
可写 |
__self__
:类实例对象本身
| class MyClass: |
| def my_method(self): |
| print("This is a method.") |
| |
| |
| obj = MyClass() |
| |
| |
| method_object = obj.my_method |
| |
| |
| bound_instance = method_object.__self__ |
| |
| |
| print(bound_instance is obj) |
| bound_instance.my_method() |
- 在这个例子中,
__self__
用于获取 method_object
所属的实例,即 obj
。这在某些场景下可能会有用,例如在装饰器中获取方法所属的对象。一般情况下,直接通过 method_object()
调用方法就足够了,而不需要显式地访问 __self__
。
__func___
:函数对象
- 这是在处理装饰器或其他需要访问原始函数的场景时可能会使用的一种技术。
| class MyClass: |
| def my_method(self): |
| print("This is a method.") |
| |
| |
| obj = MyClass() |
| |
| |
| method_object = obj.my_method |
| |
| |
| original_function = method_object.__func__ |
| |
| |
| original_function(obj) |
__doc__
:方法的文档
| class Foo(object): |
| '''doc文档所处的位置''' |
| '''第二行就不是了''' |
| def __init__(self, name, age): |
| self.name = name |
| self.age = age |
| |
| |
| f = Foo('001', 18) |
| print(f.__doc__) |
| |
__name__
:方法名称
| class MyClass: |
| def my_method(self): |
| print("This is a method.") |
| |
| |
| obj = MyClass() |
| print(obj.my_method.__name__) |
__moudle__
:方法所属模块的名称,没有则为 None
| class MyClass: |
| def my_method(self): |
| print("This is a method.") |
| |
| |
| obj = MyClass() |
| print(obj.my_method.__module__) |
| |
| |
| from test1 import obj_test1 |
| print(obj_test1.__module__) |
| |
__get__
/__set__
/__delete__
:描述器
-
官方文档
-
描述器的概念:
- 描述器就是具有“绑定行为”的对象属性,其属性访问已被描述器协议中的方法所重载:
__get__()
, __set__()
和 __delete__()
。 如果一个对象定义了以上方法中的任意一个,它就被称为描述器。
- 属性访问的默认行为是从一个对象的字典中获取、设置或删除属性。例如,
a.x
的查找顺序会从 a.__dict__['x']
开始,然后是 type(a).__dict__['x']
,接下来依次查找 type(a)
的上级基类,不包括元类。
-
来自GPT的概述
-
描述器(Descriptor)是 Python 中一种强大的工具,用于自定义属性的访问、修改和删除行为。描述器是实现了 __get__
、__set__
和 __delete__
中至少一个方法的对象。
描述器可以用于自定义类的属性行为,允许你在属性被访问、设置或删除时执行特定的操作。常见的描述器包括属性(property)、方法(method)和类方法(classmethod)。
以下是描述器的基本特性:
__get__(self, instance, owner)
: 当属性被访问时调用的方法。instance
是实例对象,owner
是拥有属性的类。
__set__(self, instance, value)
: 当属性被设置时调用的方法。instance
是实例对象,value
是设置的值。
__delete__(self, instance)
: 当属性被删除时调用的方法。instance
是实例对象。
描述器的典型应用之一是创建属性的计算值,其中 __get__
方法计算属性的值,而 __set__
方法可能用于防止对属性进行非法的赋值。
| class DescriptorExample: |
| def __init__(self, name): |
| self._name = name |
| |
| def __get__(self, instance, owner): |
| print(f"Getting value of {self._name}") |
| return instance.__dict__[self._name] |
| |
| def __set__(self, instance, value): |
| print(f"Setting value of {self._name} to {value}") |
| instance.__dict__[self._name] = value |
| |
| class MyClass: |
| descriptor_attr = DescriptorExample("descriptor_attr") |
| |
| |
| obj = MyClass() |
| obj.descriptor_attr = 42 |
| print(obj.descriptor_attr) |
| |
剩余方法可见官方文档
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了