类的内置方法(魔法方法)

类的内置方法(魔法方法)

  凡是在类内部定义,以__开头__结尾的方法,都是类的内置方法,也称之为魔法方法

  注意:类的内置方法,会在某种条件满足下自动触发

 

常用内置方法:

  1) __init__:在调用类时自动触发,通过object产生的空对象自动调用__init__()

 

  2) __new__:在__init__触发前自动触发,调用该类时,内部会通过__new__产生一个新的对象

 

  3) __getattr__:在 "对象.属性" 获取属性时,若 "没有该属性" 时触发

 

  4) __getattribute__:在 "对象.属性" 获取属性时,"无论有没有该属性" 都会触发,默认return一个None

 

  5) __setattr__:当 "对象.属性 = 属性值" ,"添加或修改属性" 时触发

 

  6) __call__:在调用对象 "对象 + ()" 时触发

 

  7) __str__:在 "打印对象" 时触发

 

  8)__getitem__:在对象通过 "对象[key]" 获取属性时触发

 

  9) __setitem__:在对象通过 "对象[key]=value值" 获取属性时触发

 

注意:1、python3中的类默认都是新式类,默认继承object类

   2、魔方方法与在类中的位置无关

 

 

1、__init__

  在调用类时自动触发,通过object类产生的空对象自动调用__init__()

 

class Demo(object):    # python3中类默认继承object类(因此python3中的类都是新式类,这里继承的object类可写可不写)
    # __init__:在调用类时自动触发
    def __init__(self):
        print("此处是__init__方法的执行..")


Demo()

  执行结果:

此处是__init__方法的执行..

 

 

2、__new__

  在__init__触发前自动触发,调用该类时,内部会通过__new__产生一个新的对象

 

class Demo(object):    # 这里的object父类可写可不写
    def __init__(self):
        print("此处是__init__方法的执行..")

    # object类中有__new__方法会默认创建一个新的空对象,但是此处被重写,不会创建一个新的空对象
    def __new__(cls, *args, **kwargs):
        print("此处是__new__方法的执行..")

        # python内部通过object类调用内部的__new__方法实现产生一个新的空对象(内存地址)
        # return object.__new__(cls, *args, **kwargs)

Demo() # __new__方法被重写,无法创建新的空对象,所以__init__方法不执行

  执行结果:

此处是__new__方法的执行..

 

 

3、__getattr__

  在 "对象.属性" 获取属性时,若 "没有该属性" 时触发

 

class Demo():
    def __new__(cls, *args, **kwargs):
        print("此处是__new__方法的执行..")
        return object.__new__(cls, *args, **kwargs)

    def __init__(self):
        print("此处是__init__方法的执行..")
    
    # __getattr__:在 "对象.属性" 获取属性时,若 "没有该属性" 时触发
    def __getattr__(self, item):
        print("此处是__getattr__方法的执行..")
        print(item)    # item在此处是属性的名字
        return "Tom is very cute..."


demo_obj = Demo()
print(demo_obj.x, "  <--- 没有x属性触发__getattr__方法return的值")    # 没有x属性
demo_obj.y = 20    # 添加y属性
print(demo_obj.y, "                   <--- 有y属性不触发__getattr__方法return的值")    # 有y属性

  执行结果:

执行结果:
此处是__new__方法的执行..
此处是__init__方法的执行..
此处是__getattr__方法的执行..
x
Tom is very cute...   <--- 没有x属性触发__getattr__方法return的值
20                    <--- 有y属性不触发__getattr__方法return的值

 

 

4、__getattribute__

  在 "对象.属性" 获取属性时,"无论有没有该属性" 都会触发,默认return一个None

  注意:如果__getattr__方法与__getattribute__方法同时存在类的内部,只会触发__getattribute__方法

 

class Demo():
    def __new__(cls, *args, **kwargs):
        print("此处是__new__方法的执行..")
        return object.__new__(cls, *args, **kwargs)

    def __init__(self):
        print("此处是__init__方法的执行..")

    def __getattr__(self, item):
        print("此处是__getattr__方法的执行..")
        print(item)
        return "Tom is very cute..."

    # __getattribute__:在 "对象.属性" 获取属性时,"无论有没有该属性" 都会触发
    def __getattribute__(self, item):
        print("此处是__getattribute__方法的执行..")
        print(item)    # item在此处是属性的名字


demo_obj = Demo()
print(demo_obj.x, "  <--- 没有x属性触发__getattribute__方法return的值(默认为None)")    # 没有x属性
demo_obj.y = 20    # 添加y属性
print(demo_obj.y, "  <--- 有y属性触发__getattribute__方法return的值(默认为None)")    # 有x属性
# 如果__getattr__与__getattribute__同时存在类的内部,只会触发__getattribute__

  执行结果:

此处是__new__方法的执行..
此处是__init__方法的执行..
此处是__getattribute__方法的执行..
x
None   <--- 没有x属性触发__getattribute__方法return的值(默认为None)
此处是__getattribute__方法的执行..
y
None   <--- 有y属性触发__getattribute__方法return的值(默认为None)

 

 

5、__setattr__

  当 "对象.属性 = 属性值" ,"添加或修改属性" 时触发

 

class Demo():
    def __new__(cls, *args, **kwargs):
        print("此处是__new__方法的执行..")
        return object.__new__(cls, *args, **kwargs)

    def __init__(self):
        print("此处是__init__方法的执行..")

    # __setattr__:当 "对象.属性 = 属性值" ,"添加或修改属性" 时触发
    def __setattr__(self, key, value):    # key是 "对象的属性名", value是 "属性值"
        print("此处是__setattr__方法的执行..")
        print(key, value)
        # self.key = value    # 不能这样设置,会出现无限递归
        # 此处是对 "对象的名称空间(字典)" 进行操作
        self.__dict__[key] = value


demo_obj = Demo()
# 原来设置属性时,会自动触发父类object中的__setattr__,内部为对象添加z属性,值为30
demo_obj.z = 30
demo_obj.z = 40
print(demo_obj.__dict__)

  执行结果:

此处是__new__方法的执行..
此处是__init__方法的执行..
此处是__setattr__方法的执行..
z 30
此处是__setattr__方法的执行..
z 40
{'z': 40}

 

 

6、__call__

  在调用对象 "对象 + ()" 时触发

 

class Demo():
    def __new__(cls, *args, **kwargs):
        print("此处是__new__方法的执行..")
        return object.__new__(cls, *args, **kwargs)

    def __init__(self):
        print("此处是__init__方法的执行..")

    # __call__:在调用对象 "对象 + ()" 时触发
    def __call__(self, *args, **kwargs):
        print("此处是__call__方法的执行..")

        # 调用对象时返回的值
        return [1, 2, 3, 4, 5]

demo_obj
= Demo() res = demo_obj() print(res)

  执行结果:

此处是__new__方法的执行..
此处是__init__方法的执行..
此处是__call__方法的执行..
[1, 2, 3, 4, 5]

 

 

7、__str__

  在 "打印对象" 时触发

  注意:__str__方法必须要有一个 "字符串" 返回值

 

class Demo():
    def __new__(cls, *args, **kwargs):
        print("此处是__new__方法的执行..")
        return object.__new__(cls, *args, **kwargs)

    def __init__(self):
        print("此处是__init__方法的执行..")

    # __str__:在打印对象时触发
    def __str__(self):
        print("此处是__str__方法的执行..")
        # __str__方法必须要有一个 "字符串" 返回值
        return "111"


demo_obj = Demo()
print(demo_obj)

  执行结果:

此处是__new__方法的执行..
此处是__init__方法的执行..
此处是__str__方法的执行..
111

 

 

8、__getitem__

  在对象通过 "对象[key]" 获取属性时触发

 

class Demo():
    def __new__(cls, *args, **kwargs):
        print("此处是__new__方法的执行..")
        return object.__new__(cls, *args, **kwargs)

    def __init__(self):
        print("此处是__init__方法的执行..")

    # __getitem__:在对象通过 "对象[key]" 获取属性时触发
    def __getitem__(self, item):
        print("此处是__getitem__方法的执行..")
        print(item)    # item在此处是属性的名字

        return self.__dict__[item]    # 返回的是对象内存空间中属性的值


demo_obj = Demo()
demo_obj.b = 50
print(demo_obj["b"])

  执行结果:

此处是__new__方法的执行..
此处是__init__方法的执行..
此处是__getitem__方法的执行..
b
50

 

 

9、__setitem__

  在对象通过 "对象[key]=value值" 获取属性时触发

 

class Demo():
    def __new__(cls, *args, **kwargs):
        print("此处是__new__方法的执行..")
        return object.__new__(cls, *args, **kwargs)

    def __init__(self):
        print("此处是__init__方法的执行..")

    def __getitem__(self, item):
        print("此处是__getitem__方法的执行..")
        return self.__dict__[item]

    # __setitem__:在对象通过 "对象[key]=value值" 获取属性时触发
    def __setitem__(self, key, value):
        print("此处是__setitem__方法的执行..")
        # print(key)    # key在此处是属性的名字
        # print(value)    # value是属性值

        self.__dict__[key] = value    # 将key:value添加到对象的名称空间中

demo_obj = Demo() demo_obj["c"] = 100 # 存属性 print(demo_obj["c"]) # 取属性值

  执行结果:

此处是__new__方法的执行..
此处是__init__方法的执行..
此处是__setitem__方法的执行..
此处是__getitem__方法的执行..
100
posted @ 2020-10-28 16:30  chchcharlie、  阅读(274)  评论(0编辑  收藏  举报