- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章详解Python常用的魔法方法由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
Python的魔法方法会在特定的情况下自动调用,且他们的方法名通常被双下划线包裹,之前我们学习的构造函数和析构函数就属于魔法方法 。
Python中同样有运算符重载,其实所有的运算符都是使用了对应的魔法方法来处理的对象的,魔法方法对应的操作符如下 。
我们来举一个简单的例子 。
class A: def __init__(self,x): self.x = x def __add__(self,other): return int(self.x)+int(other.x)a = A(3.3)b = A(5.2)print(a+b)
类似的还有反运算重载和增量复制运算,用处较少,不再解释 。
__str__(self):返回值是str类型的,当我们需要以字符串的形式输出对象时(调用print时),就会自动调用该方法,举个例子 。
class A: def __str__(self): return '我真帅'a = A()print(a)# 我真帅
__repr__(self):返回值是str类型的,当我们直接在shell中输入对象名并按下回车,就会自动调用该方法,他也有和__str__一样的功能,但如果两者你都重写了,在使用print时,__str__的优先级高,__repr__是给机器看的,__str__是给人看的,举个例子 。
>>> class A: def __str__(self): return '我真帅' def __repr__(self): return '我是世界第一帅'>>> a = A()>>> a我是世界第一帅>>> print(a)我真帅
__getattr__(self, name)
:定义当用户试图获取一个不存在的属性时的行为,其中name是属性名,是一个字符串,下同
__getattribute__(self, name)
:定义当该类的属性被访问时的行为,该方法默认返回该属性的值
__setattr__(self, name, value)
:定义当一个属性被设置时的行为,value是给该属性的值
__delattr__(self, name)
:定义当一个属性被删除时的行为
例如:
class A: def __init__(self): self.id = "Pyhon" def __getattr__(self,name): print(name+"这个属性不存在") def __getattribute__(self,name): print("我访问了"+name+"这个属性") return super().__getattribute__(name) def __setattr__(self,name,value): print("将属性"+name+"置为"+value) super().__setattr__(name,value) def __delattr__(self,name): print("将属性"+name+"删除了"); super().__delattr__(name) def fun(self): passa = A()a.namea.name = "老师"del a.namea.fun()# output:# 将属性id置为Pyhon# 我访问了name这个属性# name这个属性不存在# 将属性name置为老师# 将属性name删除了# 我访问了fun这个属性
结果可以看出,当我们访问一个属性的时候,先是调用了__getattribute__,如果该属性不存在,则再调用__getattr__ 。
使用这几个的方法的时候,要注意不要陷入无限递归,运算符重载的时候也容易犯这种错误,例如下面的错误 。
class A: def __init__(self): self.id = "Pyhon" def __setattr__(self,name,value): print("将属性"+name+"置为"+value) if(name == "id"): self.id = valuea = A()
执行这段程序的时候将陷入无限递归,原因是在__setattr__中,直接给self对象的属性赋值,而这又会调用__setattr__方法.
所以在__setattr__中,我们通常会使用父类的__setattr__方法来给self对象的属性赋值,这不会陷入无限递归,其他几个方法和运算符重载也是同理,上面程序订正后如下 。
class A: def __init__(self): self.id = "Pyhon" def __setattr__(self,name,value): print("将属性"+name+"置为"+value) if(name == "id"): super().__setattr__(name,value)a = A()# output# 将属性id置为Pyhon
__get__(self, instance, owner)
:通过其他实例对象来访问该类的实例对象时会调用该方法,返回该实例对象的引用。其中instance是访问该对象的实例对象的引用,下同,owner是访问该对象的类对象
__set__(self, instance, value)
:通过其他实例对象来给该类的实例对象赋值时会调用该方法。其中value是给该对象赋的值
__delete__(self, instance)
:通过其他实例对象来删除该类的实例对象时会调用该方法
class Fit: def __init__(self): self.height = 180 self.weight = 80 def __get__(self,instance,owner): print("get:",instance,owner) return [self.height,self.weight] def __set__(self,instance,value): print("set:",instance,value) self.height = value self.weight = value/2 def __delete__(self,instance): del self.height del self.weight print("delete:",instance)class Test: fit = Fit() t = Test()print (t.fit)t.fit = 190del t.fit# output:# get: <__main__.Test object at 0x0000023EFFA738C8> <class '__main__.Test'># [180, 80]# set: <__main__.Test object at 0x0000023EFFA738C8> 190# delete: <__main__.Test object at 0x0000023EFFA738C8>
通常情况下,上面几个魔法方法,当我们需要定义一个属性,且希望可以直接对该属性进行相应的操作,而不是通过调用方法的方式来进行操作时,我们可以定义一个该属性的类,实现上面几个魔法方法,将需要用到的属性作为其实例对象,这样就完成了,例如上面的Fit,其实就是体型类,而Test中有一个体型属性叫fit,我们在Fit中定义了一些对Fit的实例对象操作时执行的操作.
__len__(self)
:定义当该类的实例对象被len()调用时的行为
__getitem__(self, key)
:定义获取该类的实例对象中指定元素的行为,也就是说执行self[key]时的行为
__setitem__(self, key, value)
:定义设置该类的实例对象中指定元素的行为,相当于self[key] = value
__delitem__(self, key)
:定义删除该类的实例对象中指定元素的新闻,相当于del self[key]
class CountList: def __init__(self,*args): self.values = [x for x in args]#这是一个列表推导式,把args里的元素作为values的元素 self.count = {}.fromkeys(range(len(self.values)),0) def __len__(self): return len(self.values) def __getitem__(self,key): self.count[key] += 1; return self.values[key]c = CountList(1,3,5,7,9,11)print(c[1])print(c[1]+c[2])print(c.count)# output:# 3# 8# {0: 0, 1: 2, 2: 1, 3: 0, 4: 0, 5: 0}
该类中的count是记录对应元素被访问的次数,其他两个也差不多,不再举例了 。
迭代器,就是提供了迭代方法的容器,而所谓的迭代方法,就是下面这两个__iter__和__next__ 可迭代,就是提供了__iter__方法的容器,我们之前讲的字符串,列表,元组,字典,集合都是可迭代的,但他们不是迭代器,可以使用Python的内置函数iter(iterable)来获取他们相应的迭代器,而迭代器使用next(iterator)可以获取下一个元素,而这两个方法其实就是调用了迭代器的__iter__和__next__ 。
__iter__(self)
:定义获取迭代器时的行为
__next__(self)
:定义获取迭代器对应的下一个元素时的行为
class Fb: def __init__(self,n = 20): self.a = 0 self.b = 1 self.n = n def __iter__(self): return self def __next__(self): t = self.a self.a = self.b self.b = t + self.b if(self.a <= self.n): return self.a else: raise StopIterationf = Fb()for i in f: print(i,end=' ')# output:1 1 2 3 5 8 13
其中 raise 是返回一个异常,上面的程序等价于下面这个 。
class Fb: def __init__(self,n = 20): self.a = 0 self.b = 1 self.n = n def __iter__(self): return self def __next__(self): t = self.a self.a = self.b self.b = t + self.b if(self.a <= self.n): return self.a else: raise StopIterationf = Fb()it = iter(f)while True: try: i = next(it) print(i, end=' ') except StopIteration: break;
这样我们就很清楚Python中for循环的原理了,先通过iter来获取迭代器对象,然后不断调用next来获取下一个元素赋值给i,直到遇到StopIteration异常 。
到此这篇关于详解Python常用的魔法方法的文章就介绍到这了,更多相关python魔法方法内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。
原文链接:https://blog.csdn.net/qq_43713303/article/details/117419455 。
最后此篇关于详解Python常用的魔法方法的文章就讲到这里了,如果你想了解更多关于详解Python常用的魔法方法的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我想了解 Ruby 方法 methods() 是如何工作的。 我尝试使用“ruby 方法”在 Google 上搜索,但这不是我需要的。 我也看过 ruby-doc.org,但我没有找到这种方法。
Test 方法 对指定的字符串执行一个正则表达式搜索,并返回一个 Boolean 值指示是否找到匹配的模式。 object.Test(string) 参数 object 必选项。总是一个
Replace 方法 替换在正则表达式查找中找到的文本。 object.Replace(string1, string2) 参数 object 必选项。总是一个 RegExp 对象的名称。
Raise 方法 生成运行时错误 object.Raise(number, source, description, helpfile, helpcontext) 参数 object 应为
Execute 方法 对指定的字符串执行正则表达式搜索。 object.Execute(string) 参数 object 必选项。总是一个 RegExp 对象的名称。 string
Clear 方法 清除 Err 对象的所有属性设置。 object.Clear object 应为 Err 对象的名称。 说明 在错误处理后,使用 Clear 显式地清除 Err 对象。此
CopyFile 方法 将一个或多个文件从某位置复制到另一位置。 object.CopyFile source, destination[, overwrite] 参数 object 必选
Copy 方法 将指定的文件或文件夹从某位置复制到另一位置。 object.Copy destination[, overwrite] 参数 object 必选项。应为 File 或 F
Close 方法 关闭打开的 TextStream 文件。 object.Close object 应为 TextStream 对象的名称。 说明 下面例子举例说明如何使用 Close 方
BuildPath 方法 向现有路径后添加名称。 object.BuildPath(path, name) 参数 object 必选项。应为 FileSystemObject 对象的名称
GetFolder 方法 返回与指定的路径中某文件夹相应的 Folder 对象。 object.GetFolder(folderspec) 参数 object 必选项。应为 FileSy
GetFileName 方法 返回指定路径(不是指定驱动器路径部分)的最后一个文件或文件夹。 object.GetFileName(pathspec) 参数 object 必选项。应为
GetFile 方法 返回与指定路径中某文件相应的 File 对象。 object.GetFile(filespec) 参数 object 必选项。应为 FileSystemObject
GetExtensionName 方法 返回字符串,该字符串包含路径最后一个组成部分的扩展名。 object.GetExtensionName(path) 参数 object 必选项。应
GetDriveName 方法 返回包含指定路径中驱动器名的字符串。 object.GetDriveName(path) 参数 object 必选项。应为 FileSystemObjec
GetDrive 方法 返回与指定的路径中驱动器相对应的 Drive 对象。 object.GetDrive drivespec 参数 object 必选项。应为 FileSystemO
GetBaseName 方法 返回字符串,其中包含文件的基本名 (不带扩展名), 或者提供的路径说明中的文件夹。 object.GetBaseName(path) 参数 object 必
GetAbsolutePathName 方法 从提供的指定路径中返回完整且含义明确的路径。 object.GetAbsolutePathName(pathspec) 参数 object
FolderExists 方法 如果指定的文件夹存在,则返回 True;否则返回 False。 object.FolderExists(folderspec) 参数 object 必选项
FileExists 方法 如果指定的文件存在返回 True;否则返回 False。 object.FileExists(filespec) 参数 object 必选项。应为 FileS
我是一名优秀的程序员,十分优秀!