欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 产业 > Python中类的特殊方法(双下划线方法)汇总

Python中类的特殊方法(双下划线方法)汇总

2024/11/30 10:41:12 来源:https://blog.csdn.net/fengbingchun/article/details/141340532  浏览:    关键词:Python中类的特殊方法(双下划线方法)汇总

      Python中类的特殊方法(也称为双下划线方法或魔术方法)是那些以双下划线("__")开头和结尾的方法。这些方法具有特殊的意义,它们被Python解释器用于执行特定的操作,如对象初始化、属性访问、比较、迭代等。以下是一些常见特殊方法的简要汇总:

      1.初始化与析构:

      (1).__init__(self, ...):类的初始化方法,当创建类的新实例(新对象)时,Python会自动调用此方法。

      (2).__del__(self):对象的析构方法,当对象被销毁时调用,用于执行清理操作,比如关闭文件、释放外部资源等,它并不是用来删除对象或释放内存。此方法的调用时机是由Python的垃圾回收机制决定的,并不是在对象被删除时立即调用。

      (3).__new__(cls, ...):静态方法,用于创建类的实例,在__init__之前调用。通常不需要重写此方法,除非需要控制对象的创建过程。__new__是类级别的方法,而__init__是实例级别的方法。

      (4).__init_subclass__(cls, **kwargs):在子类被创建时自动调用。允许你在子类被定义时执行一些初始化操作,而不需要在子类中显式调用父类的方法。此方法在子类的__new__方法之后和__init__方法之前被调用。

      2.属性访问:

      (1).__getattr__(self, name):当访问的属性(self.__dict__)不存在时调用。适用于动态属性访问,注意与__getattribute__的区别。

      (2).__setattr__(self, name, value):用于设置或更新对象的属性。当你为对象的属性赋值时,Python会自动调用这个方法。

      (3).__delattr__(self, name):删除属性时调用。当使用del语句或delattr函数删除对象的属性时,如果类中定义了__delattr__方法,Python会调用这个方法而不是直接删除属性。

      (4).__getattribute__(self, name):访问任何属性时调用,拦截所有对对象属性的访问。谨慎重写,因为它可能导致无限递归。

      (5).__dir__(self):获取对象的所有属性名和方法名列表,用于dir()函数。

      3.容器方法:

      (1).__len__(self):当你对一个对象调用len()函数时,Python会自动查找该对象的__len__ 方法,并调用它来获取长度。

      (2).__getitem__(self, index):允许类的实例支持类似列表(或任何可迭代对象)的索引操作。这意味着你可以使用方括号[]来访问实例中的元素。当你对一个对象使用索引操作时,Python会自动查找该对象的__getitem__方法,并调用它来获取对应的值。

      (3).__setitem__(self, index, value):允许类的实例支持通过索引或键来设置项的值。当你使用像obj[index] = value这样的语法来设置类的实例中某个索引或键对应的值时,Python会自动调用该实例的__setitem__方法。

      (4).__delitem__(self, index):允许类的实例支持通过索引或键来删除项。当你使用像del obj[index]这样的语法来从类的实例中删除某个索引或键对应的项时,Python会自动调用该实例的__delitem__方法。

      (5).__iter__(self):允许类的实例支持迭代操作。当你对一个对象使用迭代器(比如使用for循环)时,Python会检查该对象是否实现了__iter__方法。如果实现了,Python会调用该方法来获取一个迭代器对象,然后使用该迭代器对象来遍历容器中的元素。该迭代器对象实现了两个方法:__iter__()返回迭代器对象本身(这允许迭代器被用在嵌套的循环中),以及__next__()用于返回容器的下一个元素。

      (6).__next__(self):用于迭代器类中,以返回迭代器的下一个项。当一个迭代器被用于循环(如for循环)中时,Python会反复调用迭代器的__next__方法来获取序列中的下一个元素,直到__next__方法抛出一个StopIteration异常,表示迭代已完成,循环将终止。

      (7).__reversed__(self):用于实现一个类的反向迭代。当你在一个对象上使用内置的reversed()函数时,Python会查找并调用该对象的__reversed__方法。这个方法应该返回一个迭代器,该迭代器会按照与原始对象相反的顺序产生元素。

      (8).__contains__(self, value):当你使用in关键字来检查某个值是否存在于某个对象中时,Python会自动调用该对象的__contains__方法。

      4.数值方法:

      (1).__add__(self, other):当你将两个类的实例相加时,Python会自动调用这两个实例中任一个的__add__方法。

      (2).__sub__(self, other):当你将类的两个实例相减时,Python会自动调用这个类的__sub__方法。

      (3).__mul__(self, other):当你将类的两个实例相乘时,Python会自动调用这个类的__mul__方法。

      (4).__truediv__(self, other):当你使用/运算符来操作两个对象时,Python会检查左侧对象的__truediv__方法是否存在。如果存在,Python会调用这个方法,并将右侧对象作为参数传入。如果不存在,Python会检查右侧对象是否有一个__rtruediv__方法,并以相反的顺序调用它。

      (5).__floordiv__(self, other):当你使用//运算符来操作两个对象时,Python会首先检查左侧对象的__floordiv__方法是否存在。如果存在,Python会调用这个方法,并将右侧对象作为参数传入。如果不存在,Python会查找右侧对象的__rfloordiv__方法,并以相反的顺序调用它。

      (6).__pow__(self, other[, modulo]):当你将类的两个实例作幂运算(**)时,Python会自动调用这个类的__pow__方法。

      (7).__abs__(self):当你对类的实例执行绝对值操作时,Python会自动调用这个类的__abs__方法。

      (8).__neg__(self):当你对类的实例执行一元负号运算符操作时,Python会自动调用这个类的__neg__方法。

      (9).__pos__(self):当你对类的实例执行一元正号运算符操作时,Python会自动调用这个类的__pos__方法。

      (10).__invert__(self):当你对类的实例执行按位取反运算符(~)操作时,Python会自动调用这个类的__invert__方法。

      (11).__float__(self):当你将类的实例作为浮点数使用时,Python会自动调用这个类的__float__方法。类似的用法还有:__complex__、__int__、__round__、__oct__、__hex__、__index__、__trunc__。

      (12).__mod__(self, other):当你将一个对象与另一个数(或支持模除操作的对象)使用%运算符时,Python会自动调用该对象的__mod__方法。

      (13).__divmod__(self, other):当你对一个对象调用divmod函数(同时返回除法运算的商和余数)时,Python会检查此对象的__divmod__方法是否存在。如果存在,Python会调用这个方法。

      (14).__lshift__(self, other):当你将一个对象与另一个数(或支持左移操作的对象)使用<<运算符时,Python会自动调用该对象的__lshift__方法。

      (15).__rshift__(self, other):当你将一个对象与另一个数(或支持左移操作的对象)使用>>运算符时,Python会自动调用该对象的__rshift__方法。

      (16).__and__(self, other):当你将一个对象与另一个对象(或值)使用&运算符时,Python会自动查找并调用左侧对象的__and__方法。

      (17).__xor__(self, other):当你将一个对象与另一个对象(或值)使用^运算符时,Python会自动查找并调用左侧对象的__xor__方法。

      (18).__or__(self, other):当你将一个对象与另一个对象(或值)使用|运算符时,Python会自动查找并调用左侧对象的__or__方法。

      (19).__radd__(self, other):当左侧操作数不支持与右侧操作数直接相加时。

      (20).__rsub__(self, other):当左侧操作数不支持与右侧操作数直接相减时。类似的用法还有__rand__、__rxor__、__ror__、__rmul__、__rturediv__、__rfloordiv__、__rmod__、__rdivmod__、__rpow__、__rlshift__、__rrshift__,Python会查找右侧对象的对应方法,并以相反的顺序调用它。

      (21).__iadd__(self, other):当你对一个对象使用+=运算符来添加一个值时,Python会自动查找并调用该对象的__iadd__方法。

      (22).__isub__(self, other):当你对一个对象使用-=运算符来减去一个值时,Python会自动查找并调用该对象的__isub__方法。类似的用法还有__imul__、__itruediv__、__ifoordiv__、__imod__、__ipow__、__ilshift__、__irshift__、__iand__、__ixor__、__ior__。

      5.字符串与序列表示:

      (1).__str__(self):当你使用print()函数打印对象,或者使用str()函数将对象转换为字符串时,Python会自动调用该对象的__str__方法。

      (2).__repr__(self):当你使用repr()函数或者在交互式Python解释器(如IDLE)中直接输入一个对象时,Python会自动调用该对象的__repr__方法。

      (3).__format__(self, format_spec):允许对象定义自己的格式化行为。当你使用字符串的format()方法时,会调用该对象的__format__方法。

      (4).__reduce__(self):当你使用pickle序列化一个对象时,如果对象定义了__reduce__方法,pickle会调用这个方法而不是使用默认的序列化逻辑。

      (5).__bytes__(self):当使用内置的bytes()函数将一个对象转换为字节序列时,如果该对象定义了__bytes__方法,则Python会调用该方法来完成转换。

      6.上下文管理:

      (1).__enter__(self):与with语句一起使用,在进入with代码块前调用。当一个对象与with语句一起使用时,Python会寻找该对象的__enter__和__exit__方法,用于在代码块执行前后自动执行资源分配和释放操作。

      (2).__exit__(self, exc_type, exc_val, exc_tb):与with语句一起使用,在退出with代码块时调用,用于执行清理操作。

      7.比较操作符:

      (1).__lt__(self, other):"<"比较操作。

      (2).__le__(self, other):"<="比较操作。

      (3).__eq__(self, other):"=="比较操作。

      (4).__ne__(self, other):"!="比较操作。

      (5).__gt__(self, other):">"比较操作。

      (6).__ge__(self, other):">="比较操作。

      (7).__bool__(self):当你将类的实例用在需要布尔值的场合时,Python会自动调用该实例的__bool__方法。

      8.其它:

      (1).__hash__(self):用于获取对象的哈希值。这个哈希值是一个整数,用于支持哈希表(如字典的键、集合的成员)的快速查找、插入和删除操作。当一个对象被用作字典的键、添加到集合(set)中或者作为另一个集合的元素时,Python会自动调用该对象的__hash__方法来获取其哈希值。

      (2).__call__(self, *args, **kwargs):当你定义一个类并实现了__call__方法后,你可以像调用普通函数那样调用这个类的实例,而Python会自动调用 __call__方法,并将传递给实例的参数传递给__call__方法。

      (3).__class__:内置属性,只读的,用于访问对象的类,非特殊方法,每个对象都有一个__class__属性,这个属性指向了创建该对象的类。

      (4).__dict__:内置属性,是一个字典,存储类的属性(包括数据属性和方法)。这个字典主要包含了在类中直接定义的属性,而不包括从基类继承的属性。

      (5).__doc__:内置属性,用于存储类或函数(包括方法)的文档字符串。

      (6).__module__:内置属性,用于标识一个类、函数、方法或变量是在哪个模块中定义的。

      (7).__name__:内置属性,如果模块是直接运行的,__name__的值会被设置为"__main__"。如果模块是被其他模块导入的,__name__的值则会被设置为该模块的名称。可以使用if __name__ == "__main__": 块来包含仅在模块作为主程序运行时才应执行的代码。

     以下为测试代码:

import colorama
import pickledef create_instance(cls, *args, **kwargs):  return cls(*args, **kwargs) class SpecialMethods(object):"""special methods of class"""'''initialization and destruction'''def __init__(self, data=[]):print(colorama.Fore.YELLOW + "call __init__ method")self.csdn = "https://blog.csdn.net/fengbingchun" # 这里会调用__setattr__ self.github = "https://github.com/fengbingchun"self.data = dataself.current = 0self.high = len(data)def __del__(self):print(colorama.Fore.YELLOW + "call __del__ method" + colorama.Style.RESET_ALL)def __new__(cls, *args, **kwargs):print(colorama.Fore.YELLOW + "call __new__ method")return super(SpecialMethods, cls).__new__(cls)def __init_subclass__(cls, **kwargs):print(colorama.Fore.YELLOW + "call __init_subclass__ method")super().__init_subclass__(**kwargs)print(f"subclass {cls.__name__} created")'''property access'''def __setattr__(self, name, value):print(colorama.Fore.YELLOW + "call __setattr__ method")self.__dict__[name] = value # 使用__dict__来避免无限递归def __getattr__(self, name):print(colorama.Fore.YELLOW + "call __getattr__ method")if name in self.__dict__:  return self.attributes[name]else:# raise ArithmeticError(f"'{type(self).__name__}' object has no attribute '{name}'")print(colorama.Fore.RED + f"'{type(self).__name__}' object has no attribute '{name}'")def __delattr__(self, name):print(colorama.Fore.YELLOW + "call __delattr__ method")if name in self.__dict__:super().__delattr__(name)else:print(colorama.Fore.RED + f"'{type(self).__name__}' object has no attribute '{name}'")# def __getattribute__(self, name):# 	print(colorama.Fore.YELLOW + "call __getattribute__ method")def __dir__(self):print(colorama.Fore.YELLOW + "call __dir__ method")default_dir = super().__dir__()modified_dir = [attr for attr in default_dir if attr != "_protected_method" and attr != "__private_method" ]return modified_dirdef _protected_method(self):  print("call _protected_method method")def __private_method(self):  pass'''container methods'''def __len__(self):print(colorama.Fore.YELLOW + "call __len__ method")return len(self.__dict__)def __getitem__(self, index):print(colorama.Fore.YELLOW + "call __getitem__ method")return self.data[index]def __setitem__(self, index, value):print(colorama.Fore.YELLOW + "call __setitem__ method")self.data[index] = valuedef __delitem__(self, index):print(colorama.Fore.YELLOW + "call __delitem__ method")del self.data[index]self.high = len(self.data)def __iter__(self):print(colorama.Fore.YELLOW + "call __iter__ method")return selfdef __next__(self):print(colorama.Fore.YELLOW + "call __next__ method")if self.current >= self.high:raise StopIterationelse:self.current += 1return self.data[self.current - 1]def __reversed__(self):print(colorama.Fore.YELLOW + "call __reversed__ method")return reversed(self.data)def __contains__(self, value):print(colorama.Fore.YELLOW + "call __contains__ method")return value in self.data'''numerical methods'''def __add__(self, other):print(colorama.Fore.YELLOW + "call __add__ method")if isinstance(other, SpecialMethods):return list(map(lambda x, y: x + y, self.data, other.data))elif isinstance(other, (int, float)):return [x + other for x in self.data]else:return NotImplementeddef __radd__(self, other):print(colorama.Fore.YELLOW + "call __radd__ method")return self.__add__(other)def __sub__(self, other):print(colorama.Fore.YELLOW + "call __sub__ method")if isinstance(other, SpecialMethods):return list(map(lambda x, y: x - y, self.data, other.data))elif isinstance(other, (int, float)):return [x - other for x in self.data]else:return NotImplementeddef __rsub__(self, other):print(colorama.Fore.YELLOW + "call __rsub__ method")return self.__sub__(other)		def __mul__(self, other):print(colorama.Fore.YELLOW + "call __mul__ method")return list(map(lambda x, y: x * y, self.data, other.data))def __truediv__(self, other):print(colorama.Fore.YELLOW + "call __truediv__ method")assert isinstance(other, (int, float))return [x / other for x in self.data]def __floordiv__(self, other):print(colorama.Fore.YELLOW + "call __floordiv__ method")assert isinstance(other, (int, float))return [x // other for x in self.data]def __pow__(self, other, modulo=None):print(colorama.Fore.YELLOW + "call __pow__ method")if modulo is not None:return [pow(x, other, modulo) for x in self.data]return [pow(x, other) for x in self.data]def __abs__(self):print(colorama.Fore.YELLOW + "call __abs__ method")return [abs(x) for x in self.data]def __neg__(self):print(colorama.Fore.YELLOW + "call __neg__ method")return [-x for x in self.data]def __pos__(self):print(colorama.Fore.YELLOW + "call __pos__ method")return self.datadef __invert__(self):print(colorama.Fore.YELLOW + "call __invert__ method")return [~x for x in self.data]def __float__(self):print(colorama.Fore.YELLOW + "call __float__ method")return float(self.data[0])def __mod__(self, other):print(colorama.Fore.YELLOW + "call __mod__ method")return [x % other for x in self.data]def __divmod__(self, other):print(colorama.Fore.YELLOW + "call __divmod__ method")assert isinstance(other, (int, float))quotient, remainder = divmod(self.data[0], other)return quotient, remainderdef __lshift__(self, other):print(colorama.Fore.YELLOW + "call __lshift__ method")return [x << other for x in self.data]def __rshift__(self, other):print(colorama.Fore.YELLOW + "call __rshift__ method")return [x >> other for x in self.data]def __and__(self, other):print(colorama.Fore.YELLOW + "call __and__ method")return [x & other for x in self.data]def __xor__(self, other):print(colorama.Fore.YELLOW + "call __xor__ method")return [x ^ other for x in self.data]def __or__(self, other):print(colorama.Fore.YELLOW + "call __or__ method")return [x | other for x in self.data]def __iadd__(self, other):print(colorama.Fore.YELLOW + "call __iadd__ method")self.data = [ x + other for x in self.data]return selfdef __isub__(self, other):print(colorama.Fore.YELLOW + "call __isub__ method")self.data = [x - other for x in self.data]return self'''string and sequence representation'''def __str__(self):print(colorama.Fore.YELLOW + "call __str__ method")return f"SpecialMethods class(csdn:{self.csdn}; github:{self.github})"def __repr__(self):print(colorama.Fore.YELLOW + "call __repr__ method")return f"SpecialMethods class(data:{self.data})"def __format__(self, format_spec):print(colorama.Fore.YELLOW + "call __format__ method")return format(str(self), format_spec)def __reduce__(self):print(colorama.Fore.YELLOW + "call __reduce__ method")return (create_instance, (SpecialMethods, self.data))def __bytes__(self):print(colorama.Fore.YELLOW + "call __bytes__ method")return str(self.data).encode("utf-8")	'''context management'''def __enter__(self):print(colorama.Fore.YELLOW + "call __enter__ method")return selfdef __exit__(self, exc_type, exc_val, exc_tb):print(colorama.Fore.YELLOW + "call __exit__ method")if exc_type is not None:print(f"Execution: {exc_type}:{exc_val}")'''comparison operators'''def __lt__(self, other):print(colorama.Fore.YELLOW + "call __lt__ method")if not isinstance(other, SpecialMethods):return NotImplementedreturn self.data[0] < other.data[0]def __le__(self, other):print(colorama.Fore.YELLOW + "call __le__ method")if not isinstance(other, SpecialMethods):return NotImplementedreturn self.data[0] <= other.data[0]def __eq__(self, other):print(colorama.Fore.YELLOW + "call __eq__ method")if not isinstance(other, SpecialMethods):return NotImplementedreturn self.data[0] == other.data[0]def __ne__(self, other):print(colorama.Fore.YELLOW + "call __ne__ method")return not self.__eq__(other)def __gt__(self, other):print(colorama.Fore.YELLOW + "call __gt__ method")if not isinstance(other, SpecialMethods):return NotImplementedreturn self.data[0] > other.data[0]def __ge__(self, other):print(colorama.Fore.YELLOW + "call __ge__ method")if not isinstance(other, SpecialMethods):return NotImplementedreturn self.data[0] >= other.data[0]def __bool__(self):print(colorama.Fore.YELLOW + "call __bool__ method")return self.data[0] != 0'''other'''def __hash__(self):print(colorama.Fore.YELLOW + "call __hash__ method")return hash(self.data[0])def __call__(self, *args, **kwargs):print(colorama.Fore.YELLOW + "call __call__ method")self._protected_method()class SubClass(SpecialMethods):passif __name__ == "__main__":colorama.init(autoreset=True)# initialization and destructionmethods1 = SpecialMethods()print("methods.special_attribute:", methods1.special_attribute)# property accessdel methods1.addrmethods1.addr = "Tianjin"print("methods.addr:", methods1.addr)del methods1.addrprint("dir:", dir(methods1))# container methodsprint("len:", len(methods1))methods2 = SpecialMethods([2, 4, 6, 8, 10])print("index3:", methods2[3])methods2[3] = -10print("indx3:", methods2[3])del methods2[3]print("index3:", methods2[3])for value in methods2:print("value:", value)for value in reversed(methods2):print("value:", value)print(5 in methods2)print(10 in methods2)# numerical methodsprint(methods2 + methods2)print(methods2 + 88)print(88 + methods2)print(methods2 - 88)print(88 - methods2)print(methods2 * methods2)print(methods2 / 2)print(methods2 // 2)print(methods2 ** 2)print(methods2 % 3)print(divmod(methods2, 2))print(methods2 << 2)print(methods2 >> 2)print(methods2 & 3)print(methods2 ^ 3)print(methods2 | 3)methods2 += 3print(methods2)methods2 -= 3print(methods2)methods3 = SpecialMethods([-2, 4, -6, 8, -10])print(abs(methods3))print(-methods3)print(+methods3)print(~methods3)print(float(methods3))# string and sequence representationprint(str(methods3))print(repr(methods3))print(format(methods3))serialized = pickle.dumps(methods3)reconstructed = pickle.loads(serialized)print(reconstructed.data)print(bytes(methods2))# context managementwith methods3 as md3:print(md3)# comparison operatorsprint(methods2 < methods3)print(methods2 <= methods3)print(methods2 == methods3)print(methods2 != methods3)print(methods2 > methods3)print(methods2 >= methods3)if methods2:print("methods2 is True")# otherprint(hash(methods2))print(hash(methods3))methods3()print("__class__:", methods3.__class__)print("__dict__:", methods3.__dict__)print("__doc__:", methods3.__doc__)print("__module__:", methods3.__module__)print("__name__:", SpecialMethods.__name__)print(colorama.Fore.GREEN + "====== test finish ======")

      执行结果如下图所示:

      GitHub:https://github.com/fengbingchun/Python_Test

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com