范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

python编程魔术方法

  一、介绍
  首先,你一定用过魔术方法,也一定见过魔术方法。以下划线开头的方法,比如:__new____init____len____add__
  这些被统称为魔术方法。
  二、举例详解
  给整数和字符串做加法:print(1 + 2)  print("hello" + "world")   # 输出:3 # 输出:helloworld
  我们写个表示城市的类,它有两个属性:城市名和人口。
  然后我们给两个城市做加法,发现不能相加:class City:     def __init__(self, city_name, pop):         self.city_name = city_name         self.pop = pop           city1 = City("深圳市", 2000) city2 = City("长沙市", 4000) city3 = city1 + city2   print(city3)  # 输出:TypeError: unsupported operand type(s) for +: "City" and "City"
  报错是说City不支持"+"号,如何让它支持"+"呢?需要给类加上魔术方法__add__就可以相加了。
  我们给City添加一个__add__的方法,城市相加,人口相加,创建一个新的城市:class City:     def __init__(self, city_name, pop):         self.city_name = city_name         self.pop = pop      def __add__(self, city):         new_city_name = self.city_name + city.city_name         new_pop = self.pop + city.pop         return City(new_city_name, new_pop)      city1 = City("深圳市", 2000) city2 = City("长沙市", 4000) city3 = city1 + city2 print(city3.city_name) print(city3.pop) print(city3)  # 输出:深圳市长沙市 # 输出: 6000 # 输出: <__main__.City object at 0x0000020937A5B7C8>
  这说明__add__有一定的魔力,当我们用到加号"+"时,python就回去寻找这个方法,如果这个对象没有这个方法就会报错。
  python中,所有的运算符都是通过魔术方法来实现的。
  如果我们在City类有以下方法,就可以做加减乘除了:__add__(self, other) 定义加法的行为:+ __sub__(self, other) 定义减法的行为:-__mul__(self, other) 定义乘法的行为:*__truep__(self, other) 定义真除法的行为:/
  我们再来打印int和str查看他们的方法,int有加减乘除,str只有__add__ __mul__,它只能做加法和乘法:print(dir(int))  # 输出:["__abs__", "__add__", "__and__", "__bool__", "__ceil__", "__class__", "__delattr__", "__dir__", "__pmod__", "__doc__", "__eq__", "__float__", "__floor__", "__floorp__", "__format__", "__ge__", "__getattribute__", "__getnewargs__", "__gt__", "__hash__", "__index__", "__init__", "__init_subclass__", "__int__", "__invert__", "__le__", "__lshift__", "__lt__", "__mod__", "__mul__", "__ne__", "__neg__", "__new__", "__or__", "__pos__", "__pow__", "__radd__", "__rand__", "__rpmod__", "__reduce__", "__reduce_ex__", "__repr__", "__rfloorp__", "__rlshift__", "__rmod__", "__rmul__", "__ror__", "__round__", "__rpow__", "__rrshift__", "__rshift__", "__rsub__", "__rtruep__", "__rxor__", "__setattr__", "__sizeof__", "__str__", "__sub__", "__subclasshook__", "__truep__", "__trunc__", "__xor__", "bit_length", "conjugate", "denominator", "from_bytes", "imag", "numerator", "real", "to_bytes"]  print(dir(str))  # 输出:["__add__", "__class__", "__contains__", "__delattr__", "__dir__", "__doc__", "__eq__", "__format__", "__ge__", "__getattribute__", "__getitem__", "__getnewargs__", "__gt__", "__hash__", "__init__", "__init_subclass__", "__iter__", "__le__", "__len__", "__lt__", "__mod__", "__mul__", "__ne__", "__new__", "__reduce__", "__reduce_ex__", "__repr__", "__rmod__", "__rmul__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "capitalize", "casefold", "center", "count", "encode", "endswith", "expandtabs", "find", "format", "format_map", "index", "isalnum", "isalpha", "isascii", "isdecimal", "isdigit", "isidentifier", "islower", "isnumeric", "isprintable", "isspace", "istitle", "isupper", "join", "ljust", "lower", "lstrip", "maketrans", "partition", "replace", "rfind", "rindex", "rjust", "rpartition", "rsplit", "rstrip", "split", "splitlines", "startswith", "strip", "swapcase", "title", "translate", "upper", "zfill"]
  三、魔术方法的定义魔术方法对python是至关重要的,python是运行在魔术方法的轮子之上的,没有魔术方法就没有python。形如__xxx__的方法自己随意定义的__xxx__方法是没有用的python运算符都对应着一个魔术方法,所以魔术方法都是内定的,具有特殊的含义for循环,被循环的对象之所以被循环,是因为他们有__iter__和__next__len(),del都有对应的魔术方法列表获取元素也有对应的魔术方法
  列表为什么能获取元素, __getitem__,可以再任何一个类里加上这个方法,然后也就可以用[]方括号来获取元素:cities = ["珠海市", "厦门市", "青岛市"] print(cities[0]) # 输出:珠海市  print(dir(list))  # 输出:["__add__", "__class__", "__contains__", "__delattr__", "__delitem__", "__dir__", "__doc__", "__eq__", "__format__", "__ge__", "__getattribute__", "__getitem__", "__gt__", "__hash__", "__iadd__", "__imul__", "__init__", "__init_subclass__", "__iter__", "__le__", "__len__", "__lt__", "__mul__", "__ne__", "__new__", "__reduce__", "__reduce_ex__", "__repr__", "__reversed__", "__rmul__", "__setattr__", "__setitem__", "__sizeof__", "__str__", "__subclasshook__", "append", "clear", "copy", "count", "extend", "index", "insert", "pop", "remove", "reverse", "sort"]
  我们使用最多的方法一定是__new__和__init__, 在新建方法的时候,都会调用到这两个方法:city1 = City("深圳市", 2000) city2 = City("长沙市", 4000)
  四、魔术方法的好处python的一个点,可以非常灵活地实现运算符通过实现魔术方法可以让自定义的类支持各种操作
  五、魔术属性
  不止有魔术方法,还有魔术属性,形如"__yyy__",通常是python自动设置的属性,我们可以使用这些属性,比如:print(__file__) # 打印出当前文件所在地目录和文件名 print(__name__) # 判断当前模块是被导入进来的,还是被直接调用的   # 输出:C:/Users//Desktop/magic_method.py # 输出:__main__ (或者输出文件名)
  六、查看所有魔术方法和魔术属性import gc  # gc管理内存的  print(" ".join(sorted({attrname for item in gc.get_objects()                          for attrname in dir(item) if attrname.startswith("__")}))) # 从内存中打印所有对象,并打印出每个对象中的魔术方法  # 输出: __about__ __abs__ __abstractmethods__ __add__ __aenter__ __aexit__ __aiter__ __all__ __and__ __anext__ __annotations__ __author__ __await__ __base__ __bases__ __basicsize__ __bool__ __breakpointhook__ __build_class__ __builtins__ __cached__ __call__ __callback__ __cause__ __class__ __closure__ __code__ __complex__ __concat__ __contains__ __context__ __copy__ __create_codec __debug__ __defaults__ __del__ __delattr__ __delete__ __delitem__ __dict__ __dictoffset__ __dir__ __displayhook__ __doc__ __enter__ __eq__ __excepthook__ __exit__ __file__ __flags__ __float__ __floorp__ __format__ __fspath__ __func__ __ge__ __get__ __getattr__ __getattribute__ __getitem__ __getnewargs__ __getstate__ __globals__ __gt__ __hash__ __iadd__ __iand__ __iconcat__ __ifloorp__ __ilshift__ __imatmul__ __imod__ __import__ __imul__ __index__ __init__ __init_subclass__ __instancecheck__ __int__ __interactivehook__ __inv__ __invert__ __ior__ __ipow__ __irshift__ __isabstractmethod__ __isub__ __itemsize__ __iter__ __itruep__ __ixor__ __kwdefaults__ __le__ __len__ __loader__ __lshift__ __lt__ __map_gb18030ext __map_gb2312 __map_gbcommon __map_gbkext __matmul__ __missing__ __mod__ __module__ __mro__ __mul__ __name__ __ne__ __neg__ __new__ __next__ __not__ __objclass__ __or__ __package__ __path__ __pos__ __pow__ __prepare__ __qualname__ __radd__ __rand__ __reduce__ __reduce_ex__ __repr__ __reversed__ __rmod__ __rmul__ __ror__ __rshift__ __rsub__ __rxor__ __self__ __set__ __setattr__ __setitem__ __setstate__ __sizeof__ __slots__ __spec__ __stderr__ __stdin__ __stdout__ __str__ __sub__ __subclasscheck__ __subclasses__ __subclasshook__ __suppress_context__ __text_signature__ __traceback__ __truep__ __weakref__ __weakrefoffset__ __wrapped__ __xor__
  七、常见的魔术方法初始化和构造构造方法 __new__(cls,other) 对象实例化时自动触发(在__init__之前触发)初始化方法 __init__(self,other) 对象实例化之后立即触发析构方法 __del__(self) 当该类对象被销毁时
  一元运算符__pos__(self) 定义正号的行为:+x __neg__(self) 定义负号的行为:-x __abs__(self) 定义当被 abs() 调用时的行为 __invert__(self) 定义按位求反的行为:~x __round__(self) 调用round()方法时被调用 __floor__(self) 调用math.floor()方法时被调用 __ceil__(self) 调用math.ceil()方法时被调用 __trunc__(self) 调用math.trunc()方法时被调用
  增量赋值__iadd__(self, other) 定义赋值加法的行为:+= __isub__(self, other) 定义赋值减法的行为:-= __imul__(self, other) 定义赋值乘法的行为:*= __itruep__(self, other) 定义赋值真除法的行为:/= __ifloorp__(self, other) 定义赋值整数除法的行为://= __imod__(self, other) 定义赋值取模算法的行为:%= __ipow__(self, other[, modulo]) 定义赋值幂运算的行为:**= __ilshift__(self, other) 定义赋值按位左移位的行为:<<= __irshift__(self, other) 定义赋值按位右移位的行为:>>=  __iand__(self, other) 定义赋值按位与操作的行为:&= __ixor__(self, other) 定义赋值按位异或操作的行为:^= __ior__(self, other) 定义赋值按位或操作的行为:|=
  类型转换__int__(self) 定义当被 int() 调用时的行为(需要返回恰当的值) __float__(self) 定义当被 float() 调用时的行为(需要返回恰当的值) __complex__(self) 定义当被 complex() 调用时的行为(需要返回恰当的值) __oct__(self) 定义当被 oct() 调用时的行为(需要返回恰当的值) __hex__(self) 定义当被 hex() 调用时的行为(需要返回恰当的值) __trunc__(self) 定义当被 trunc() 调用时的行为(需要返回恰当的值) __index(self)__ 当对象是被应用在切片表达式中时,实现整形强制转换
  字符串str(self) 调用str()方法时被调用 repr 调用repr()方法时被调用 unicode 调用unicode()方法时被调用 format 调用string.format()方法时被调用 hash 调用hash()方法时被调用 nonzero 调用nonzero ()方法时被调用 dir 调用 dir()方法时被调用 sizeof 调用sys.get sizeof()方法时被调用
  属性getattr(self,name) 定义当用户试图获取一个不存在的属性时的行为setattr(self,name,value) 定义对属性的赋值行为,无论属性是否存在delattr(self,name) 定义删除属性的行为
  操作符__add__(self, other) 定义加法的行为:+ __sub__(self, other) 定义减法的行为:- __mul__(self, other) 定义乘法的行为:* __truep__(self, other) 定义真除法的行为:/ __floorp__(self, other) 定义整数除法的行为:// __mod__(self, other) 定义取模算法的行为:% __pow__(self, other[, modulo]) 定义当被 power() 调用或 ** 运算时的行为 __ lt__(self, other): 定义小于号的行为:x < y 调用 x.lt(y) __ le__(self, other): 定义小于等于号的行为:x <= y 调用 x.le(y) __ eq__(self, other) : 定义等于号的行为:x == y 调用 x.eq(y) __ ne__(self, other): 定义不等号的行为:x != y 调用 x.ne(y) __ gt__(self, other): 定义大于号的行为:x > y 调用 x.**gt(y) __ ge__(self, other) : 定义大于等于号的行为:x >= y 调用 x.ge(y) __lshift__(self, other) 定义按位左移位的行为:<< __rshift__(self, other) 定义按位右移位的行为:>> __and__(self, other) 定义按位与操作的行为:& __xor__(self, other) 定义按位异或操作的行为:^  __or__(self, other) 定义按位或操作的行为:|
  八、魔术方法的操作实例__new__常用操作# 2 new调用其他类 class OtherClass1:     print("其他类")     a = "其他类的值"   other_obj = OtherClass1()   # 3 new 实现单例模式 class OtherClass2:     def __init__(self):         print(" 触发了OtherClass2的初始化 ")   other_obj1 = OtherClass2() other_obj2 = OtherClass2() print("other_obj1的id :", id(other_obj1)) print("other_obj2的id :", id(other_obj2))   # 装饰器单例模式 def class_one_case(cls):     # 空字典储存 类 和 类实例(key:value)     instace = {}      def inner(*args, **kwargs):         # 如果类不在字典中实例化对象储存,否者用字典中的对象         if cls not in instace:             instace[cls] = cls(*args, **kwargs)             return instace[cls]         else:             return instace[cls]              return inner   @class_one_case class City(object):     instance = None      def __init__(self, city_name):         print("触发了初始化方法")         self.city_name = city_name      # def __new__(cls, *args, **kwargs):     #     print("触发了构造方法")     # return super().__new__(cls)  # 1 重写__new__方法,调用父类的__new__方法创建对象,并进行返回     # return object.__new__(cls)      # return other_obj  # 2 返回其他类的对象      # 3 如果 instance 为None 实例化对象,否则用第一次实例的对象     # if not cls.instance:     #     print("instance为:  ", cls.instance)     #     cls.instance = object.__new__(cls)     #     return cls.instance     # else:     #     print("instance为: ", cls.instance)     #     return cls.instance      def run_one_case(self):         print("单例装饰器 run_one_case : ", self.city_name)   # city1 = City("深圳市") # print(city1.city_name)   # city2 = City() # print(city2.a)  city3 = City("深圳市") city4 = City("深圳市") print("city3的id :", id(city3)) print("city3的id :", id(city4)) # 所以city3创建的属性,city4一样有 city3.pop = 1234 print("city4的pop为:", city4.pop) # 单例装饰器 city4.run_one_case()
  __str__和__repr__常用操作使用 format函数、str函数、print打印对象时会优先触发str方法 没定义str方法的情况下,会再去找repr方法,如果都没有,那么就会去找父类的str方法。如果父类没有str方法,会找父类的repr方法。 如果继承object的话,object里面肯定有str方法的。除非是继承一个自己定义的类。
  repr在交互环境下和内置函数处理对象时,它只会触发repr方法,如果repr方法不存在,会找父类的repr方法。 repr方法是str方法的备胎。但是repr方法不能拿str方法做备胎。父类是第二轮备胎。 print打印是由str方法决定的,交互环境下是由repr方法决定的。
  什么使用str方法,什么时候用repr方法?str和repr方法都是返回字符串。在str方法里面返回的是字符串,直观的描述信息。str方法返回内容是给用户看的,返回是直接的描述信息。repr返回的东西是给程序员看的。程序员能看到是哪个类出来的对象,知道最开始的样子。
  如果我们想让print打印出来好看,可以定义__str__的方法:class City:     def __init__(self, city_name, pop):         self.city_name = city_name         self.pop = pop      def __add__(self, city):         new_city_name = self.city_name + city.city_name         new_pop = self.pop + city.pop         return City(new_city_name, new_pop)      # 打印就会调用这个方法,如果str方法不存在,会去触发repr方法,打印出repr方法的内容:     def __str__(self):         print("触发了 __str__ 方法")         return f"{self.city_name} : {self.pop}"      def __repr__(self):         print("__repr__被触发")         # 报错:TypeError: __repr__ returned non-string (type NoneType)         # repr返回的不是个字符串,是个None。必须返回字符串。         return "
币圈那些事俄罗斯中央银行俄罗斯中央银行正计划对数字卢布的交易收取费用金色财经报道,俄罗斯中央银行(CBR)监管机构金融技术部主任KirillPronin透露,俄罗斯中央银行正计划对数字卢布的联想与司马南之争启示录(2)最近,司马南发布了不少关于联想集团涉及国有资产流失天价薪酬与退休金的视频,引起了不小的反响,尤其是联想的柳传志也亲临论战的一线,更不惜动用法律手段。作为吃瓜群众,我们无法判定事情的华为曾经的顶级旗舰,鸿蒙OS2K屏256GB存储,如今降至2000元考虑到华为现在的处境,基本上每一次推出一款新5G机,都会引起大家的关注。因为芯片缺乏的缘故,最近华为也开始做起了二手机的生意。如果是其他厂商的二手机,可能热度不会很高,但是华为这里苹果iPhone用户想用C口?没那么容易全世界电子产品将逐渐统一使用C口标准这件事,按理来说,在各路组织和极力推动下,应该是不可阻挡的,各路厂商要做的不是反对,而是去适应,特别是欧盟的强硬表态让这件事实施起来似乎只是时间小米新款Note11系列智商税?居然还没有老款好在11月1日小米新款手机红米note11系列已经发布了,但是距离上一代机型红米note10系列仅仅隔了5个月时间,那新款到底有什么提升呢?下面给大家来详细对比一下。处理器方面首先是芯片半导体大涨,新能源大涨,大盘继续上涨,接下来这些也会大涨芯片半导体大涨,新能源大涨,大盘继续上涨,接下来这些也会大涨今天三大指数高开高走并稳定在高位,为本周整了一个非常漂亮的开门红,并且成交量也有所放大,接下来行情十分看好。本人之前说,锤子手机复活?知名手机品牌宣布回归邀请函居然是锤子11月22日消息,前几日酷派手机官微宣布,将在12月1日晚7点举行发布会,推出COOL20Pro新机。今天上午,酷派官方公布新品发布会邀请函,里面居然赠送了一柄锤子,造型和锤子手机联想从民族品牌,到司马南的怒怼,它到底经历了什么?联想从民族品牌到滚出中国,再到网红司马南的怒怼,它到底经历了什么?某想是中科院计算所的长子,创办初期,计算所从物力人力财力科技成果等方面给予强力支持。在初创时期,依托计算所资源,还小鹏汽车又陷维权门,车主被抬出广州车展现场人民数字TMT讯11月19日,信贷服务APP还呗投放的楼宇广告引发巨大争议。打老婆的人不借,不打老婆的即时到账。的广告语将还呗推上了舆论的风口浪尖,截至发稿,还呗方面并未对人民数字直呼好家伙!为缓解港口压力美国竟然这么做,机场变港口。。亚马逊国内首个产业带集货运营中心落地义乌近日,亚马逊国内首个产业带集货运营中心落地义乌,亚马逊全球物流团队义乌服务中心同时启用。亚马逊义乌仓占地3000平方米,已于9月试运营,目前美国520亿狗粮未到账,台积电三星态度大不同印度趁机出手了全球缺芯危机爆发后,各大芯片企业都忙于扩建产能,以此来满足正常供应,但在这个关键的时期,美国却站出来以各种理由,企图将全球芯片企业归为己有。先是修改芯片规则,让台积电等芯片企业无法
西部数据(WDC。US)日本工厂材料受污染闪存设备供应将减少智通财经APP获悉,西部数据(WDC。US)周三表示,其在日本的两家制造工厂的某些材料受到污染,将导致闪存设备的供应减少。据悉,上述两家工厂为西部数据与合资伙伴铠侠共同运营。根据西优步就窃取谷歌无人驾驶技术案与涉案工程师达成和解鞭牛士2月11日消息,据华尔街日报消息,优步解决关于其涉及窃取谷歌无人驾驶汽车技术的一桩破产法庭诉讼,同意与一名前工程师达成和解。该工程师之前声称,在他盗用商业机密一事上,优步也负C数据输入(输出)from(to)keyboard(screen)filestringC和C中有三类输入输出操作standardIO(标准IO),通常是指用键盘做入输入,显示屏做为输出fileIO(文件IO),硬盘文件既可以是数据输入源,也可以是输出的去向。stri恶意软件开发者主动公开MazeEgregorSekhmet解密密钥昨晚,据称是恶意软件开发者在国外BleepingComputer论坛上发帖,公开了MazeEgregor和Sekhmet勒索软件操作的主解密密钥。经安全公司Emsisoft确认这些大公司早报喜茶回应裁员30王者荣耀1月收入环比大增92(整理胡毓靖)今天是2月10日星期四,过去24小时的大公司新闻包括腾讯回应应届生怼管理层被标记永不录用严重失实喜茶回应裁员30因使用过期食材,星巴克两门店合计被罚百余万元1月王者荣鸿蒙来袭,抢先升级体验好,看看拥抱鸿蒙的五大社交软件有哪些?中国人自己的手机操作系统来了!6月2日晚上,华为公司举行HarmonyOS及华为全场景新品发布会,正式发布了鸿蒙手机操作系统。鸿蒙苹果安卓开始呈现三足鼎立的现象,而就在鸿蒙发布会上华为看来现在是618最热门手机品牌?用过mate系列的都知道原因现在看起来,华为手机还是很多人支持的,这次618至少现在看起来,华为手机的预售是第一?其实华为真正的中高端手机也就是mate系列确实不错!这应该算最近几年安卓手机里面性能最均衡的!微信越来越QQ化更新频繁,功能不实用微信作为一个几亿人在同时使用的社交软件,拥有非常庞大的用户基础,所以微信的每一次更新,都会引起网友一阵讨论。今年年初的时候,微信8。0也是在万众瞩目中上线,当时微信8。0在微博上的荣耀50系列将无缘麒麟芯片,首发骁龙778G最近高通发布了一款全新的中端芯片,骁龙778G,此款芯片与之前发布的骁龙780G综合实力上来看差距不大,据悉荣耀50系列将全线搭载此芯片。骁龙778G芯片采用四颗主频为2。4GHz三星手机用户看过来请查收这份拍照功能指南当下,市面上号称影像旗舰的手机有很多,这些旗舰的传感器硬件素质都不差,随便拉出一个来都可谓出类拔萃。但是手机影像传感器的硬件堆料是身为旗舰的基本要求,用户真正关心的还是拍摄体验的便携程梁建章提议,生一个孩子100万,上市公司这叫虚假信息携程董事局主席梁建章先生这个议题生一个孩子100万很好慢牛哥举双手双脚赞成但细细品味似乎没法实施尤其是在中国但他所呼喊的的的确确是大多数人的呼声与白岩松笨重的说教比起来这种一心只为