10.python魔术方法(10. Python magic method)

class Myclass(object):
    # def __new__(self):
    #     pass
    # 在实例化是会触发,它比 __init__早( __new__ 造出裸替的人,__init__ 穿衣服)
    def __init__(self):
        # print("__init__方法执行")
        self.age = 18

    # def __call__(self):
    #     # print('实例加括号就执行,在 __init__后执行,可以更改原来的一些实例属性')
    # self.name = 'makuo'
    # del self.age

    # def __str__(self):
    #     return '使用 print 打印对象时 会触发'
    #def __repr__(self):
    #    return '使用python解释器里面直接输入实例化后的对象会触发'
    # def __del__(self):
    #     pass
    #     # 对象回收输出会触发

    def __setattr__(self, key, value):
        # .拦截方法 ,对象加点赋值 触发这个方法
        # pass
        # print(self.__dict__)
        value = value * 5

        # 属性赋值,一定要写这一行
        self.__dict__[key] = value

    def __getattr__(self, item):
        # .拦截方法, 对象加点获取值 触发这个方法 , 当类属性不存在时会触发
        print('aa')
        self.item = 1
        return self.item
   def __setitem__(self, key, value):
        # 中括号拦截
        self[key]=value
    def __getitem__(self,key):
        # 中括号拦截
        return self[key]


# a1=Myclass()
# a1.name='ma'
# print(a1.name)

# 作业1: 写一个类,如果name属性非字符串,就不让放

# 方法1
# class Person(object):
#     def __init__(self,name):
#         if isinstance(name,str):
#             self.name = name
#         else:
#             raise AttributeError('name 属性必须是str')
#
# p1=Person('ma')
# p1=Person(11)
# 方法2
class Person(object):
    def __init__(self, name):
        self.name = name

    def __setattr__(self, key, value):
        if key == 'name' and not isinstance(value, str):
            raise AttributeError('name属性不能是str')
        else:
            self.__dict__[key] = value


# p1=Person('makuo')
# p1=Person(111)
# 方法3: 还有其他 __new__ ,__call__ 方法也可以

# 作业2:有类 Myclass,实例化产生m1,
# 如何让对象 可以 采用 m1['name']='ma'
# 可以使用  print(m1['name'])
# 方法1
# class Myclass(object):
#     def __setitem__(self, key, value):
#         setattr(self, key, value)  # 反射
#     def __getitem__(self,key):
#         return getattr(self, key) #反射取值
# m1 = Myclass()
# m1['name'] = 'makuo'
# print(m1['name'])

# 作业3:字典支持 .取值
# class Mydic(dict):
#     def __getattr__(self, key):
#         return self[key]
#
#     def __setitem__(self, key, value):
#         self[key]=value
#
#
# mydic = Mydic(name='makuo', age=18)
# mydic.gender='male'
# print(mydic.name)
# print(mydic.gender)

————————
class Myclass(object):
    # def __new__(self):
    #     pass
    # 在实例化是会触发,它比 __init__早( __new__ 造出裸替的人,__init__ 穿衣服)
    def __init__(self):
        # print("__init__方法执行")
        self.age = 18

    # def __call__(self):
    #     # print('实例加括号就执行,在 __init__后执行,可以更改原来的一些实例属性')
    # self.name = 'makuo'
    # del self.age

    # def __str__(self):
    #     return '使用 print 打印对象时 会触发'
    #def __repr__(self):
    #    return '使用python解释器里面直接输入实例化后的对象会触发'
    # def __del__(self):
    #     pass
    #     # 对象回收输出会触发

    def __setattr__(self, key, value):
        # .拦截方法 ,对象加点赋值 触发这个方法
        # pass
        # print(self.__dict__)
        value = value * 5

        # 属性赋值,一定要写这一行
        self.__dict__[key] = value

    def __getattr__(self, item):
        # .拦截方法, 对象加点获取值 触发这个方法 , 当类属性不存在时会触发
        print('aa')
        self.item = 1
        return self.item
   def __setitem__(self, key, value):
        # 中括号拦截
        self[key]=value
    def __getitem__(self,key):
        # 中括号拦截
        return self[key]


# a1=Myclass()
# a1.name='ma'
# print(a1.name)

# 作业1: 写一个类,如果name属性非字符串,就不让放

# 方法1
# class Person(object):
#     def __init__(self,name):
#         if isinstance(name,str):
#             self.name = name
#         else:
#             raise AttributeError('name 属性必须是str')
#
# p1=Person('ma')
# p1=Person(11)
# 方法2
class Person(object):
    def __init__(self, name):
        self.name = name

    def __setattr__(self, key, value):
        if key == 'name' and not isinstance(value, str):
            raise AttributeError('name属性不能是str')
        else:
            self.__dict__[key] = value


# p1=Person('makuo')
# p1=Person(111)
# 方法3: 还有其他 __new__ ,__call__ 方法也可以

# 作业2:有类 Myclass,实例化产生m1,
# 如何让对象 可以 采用 m1['name']='ma'
# 可以使用  print(m1['name'])
# 方法1
# class Myclass(object):
#     def __setitem__(self, key, value):
#         setattr(self, key, value)  # 反射
#     def __getitem__(self,key):
#         return getattr(self, key) #反射取值
# m1 = Myclass()
# m1['name'] = 'makuo'
# print(m1['name'])

# 作业3:字典支持 .取值
# class Mydic(dict):
#     def __getattr__(self, key):
#         return self[key]
#
#     def __setitem__(self, key, value):
#         self[key]=value
#
#
# mydic = Mydic(name='makuo', age=18)
# mydic.gender='male'
# print(mydic.name)
# print(mydic.gender)