先划一下重点:python
魔法方法的命名规则:方法名(先后各有2个下划线)。函数
一般状况下,不会主动去调用魔法方法,而是在知足必定的条件下,会自动去调用魔法方法。3d
经常使用的魔法方法有6个,分别是:new、del、str、repr、bytes、call,下面我为你们一一讲解。code
class Person: # __new__不用@classmethod修饰的一个类方法 # 在建立对象的时候,会首先调用该方法 # 若是在该方法中,返回当前类的对象(也即建立对象),接下来会调用__init__方法,对对象进行初始化。不然,__init__方法不会获得执行 def __new__(cls): return super().__new__(cls) # 这行代码是建立对象,只是我如今不太明白 Person() # 在咱们写类的时候,不须要写这个。这里讲述一下,只是想让咱们知道。在建立对象的时候,__new__方法比__init__方法,先调用
若一个类中既有new方法,也有init方法,当咱们建立对象时候,首先执行new方法。orm
假如,new方法中没有return super().new(cls) ,则不会执行init方法。写上之后,表示再次建立一个对象才会执行init方法。对象
# 第一段代码 class Person: def __new__(cls): print("__new__执行") return super().__new__(cls) # 这行代码是建立对象,只是我如今不太明白 def __init__(self): print("__init__执行") p = Person() # 第二段代码 class Person: def __new__(cls): print("__new__执行") # return super().__new__(cls) # 假如不返回,当前类的对象,__init__就不会执行 def __init__(self): print("__init__执行") p = Person() # 由于,这里建立的对象,先去执行new方法了
结果以下:blog
在销毁对象的时候(对象指的是咱们本身建立的对象),会首先调用该方法。字符串
class Person: def __init__(self): print("__init__执行") # 在该方法中,能够执行一些清理工做 def __del__(self): print("该对象已经被销毁") p = Person() # 能够看出,由于没有对象销毁,因此不会调用该方法
结果以下:get
class Person: def __init__(self): print("__init__执行") def __del__(self): print("该对象已经被销毁") p = Person() del p
结果以下:input
class Person: def __new__(cls): print("__new__执行") return super().__new__(cls) def __init__(self): print("__init__执行") def __del__(self): print("该对象已经被销毁") # 在使用内建函数(str,format,print)的时候,会自动调用该方法 # 该方法须要返回一个str类型的对象 # def __str__(self): # return "Person类型的对象" p = Person() print(p)
结果以下:
class Person: def __new__(cls): print("__new__执行") return super().__new__(cls) def __init__(self): print("__init__执行") # 在使用内建函数(str,format,print)的时候,会自动调用该方法 # 该方法须要返回一个str类型的对象 def __str__(self): return "Person类型的对象" p = Person() p
结果以下:
class Person: def __new__(cls): print("__new__执行") return super().__new__(cls) def __init__(self): print("__init__执行") # 在使用内建函数(str,format,print)的时候,会自动调用该方法 # 该方法须要返回一个str类型的对象 def __str__(self): return "Person类型的对象" p = Person() print(p)
结果以下:
class Person: def __new__(cls): print("__new__执行") return super().__new__(cls) def __init__(self): print("__init__执行") def __del__(self): print("该对象已经被销毁") def __str__(self): return "Person类型的对象" # __str__ 与 __repr__ 的区别:两者都是返回对象的字符串表示。 # 不一样的是:__str__ 返回的一般是让人容易阅读的格式。__repr__返回的是面向Python解释器的,一般格式:<内容> def __repr__(self): return "<Person class>" p = Person() print(str("abc")) # 结果是abc,这个更加接近人阅读模式 print(repr("abc")) # 结果是'abc',字符串原本就是带引号的,因此这个和python解释器更相近
结果以下:
该方法在使用内建函数(bytes)的时候,会自动调用.
class Person: def __new__(cls): print("__new__执行") return super().__new__(cls) def __init__(self): print("__init__执行") def __del__(self): print("该对象已经被销毁") def __str__(self): return "Person类型的对象" def __repr__(self): return "<Person class>" def __bytes__(self): return b"byte person class" p = Person() print(bytes(p))
结果以下:
把对象当成函数来使用的时候,会自动调用。
class Person: def __new__(cls): print("__new__执行") return super().__new__(cls) def __init__(self): print("__init__执行") def __del__(self): print("该对象已经被销毁") def __str__(self): return "Person类型的对象" def __repr__(self): return "<Person class>" def __bytes__(self): return b"byte person class" # 把对象当成函数来使用的时候,会自动调用该方法 def __call__(self): print("把对象当成函数来使用的时候") p = Person() p()
结果以下:
这4个函数分别是:hasattr、getattr、delattr、setattr,下面咱们一一来说述。
class Person(): pass p = Person() print(hasattr(p,"name")) p.name = "3417" print(hasattr(p,"name"))
结果以下:
class Person(): pass p = Person() print(getattr(p, "name"))
结果以下:
class Person(): pass p = Person() p.name = "关注一波?" print(getattr(p, "name"))
结果以下:
class Person(): pass p = Person() print(getattr(p,"age","没有属性返回的默认值"))
结果以下:
class Person(): pass p = Person() setattr(p,"age",20) print(p.age)
结果以下:
class Person(): pass p = Person() setattr(p,"age",20) delattr(p,"age") print(hasattr(p,"age"))
结果以下:
注意1 :动态操做属性没有直接操做属性简便,可是比直接访问属性灵活。
注意2 :直接访问属性必须在写代码时,就须要知道属性的名字,而动态操做属性没有此限制(这在其余语言中叫作'"反射")。
class Person(): pass p = Person() unknown = input("请输入属性名:") value = input("请输入属性值:") setattr(p, unknown, value) print(getattr(p, unknown))
结果以下: