day45(1)

面向对象高级(待持续补充)

# 递归现象的产生
#       -通过反射赋值 setattr(obj,key,value)
#       -self.key = value
# 避免方法
# (1)self.__dict__[key] = value
# (2)object.__setattr__(self,key,value)

# class Foo:
#     def __init__(self, name):
#         self.name = name  # 在这里会触发__setattr__的执行,所以如果重写了__setattr__,那么就会产生递归
#
#     def __setattr__(self, key, value):
#         if key == 'age':
#             if isinstance(value, int):
#                 # 往对象中放属性,反射
#                 # setattr(self,key,value)       # setattr本质还是调用了self.key=value,会发生递归
#                 # self.age = value              # 也会发生递归
#                 # 避免递归问题:
#                 # (1)
#                 # self.__dict__[key] = value
#                 # (2)普通函数,有几个参数,就传几个参数
#                 object.__setattr__(self, key, value)
#             else:
#                 raise Exception('不让放')
#         else:
#             object.__setattr__(self, key, value)
#
#     def printsize(self):
#         print(self.__size)
#
#     def __getattr__(self, item):        # 重写__getattr__
#         print(item)             # item 就是 key
#         return 99               # 如果赋予了返回值,那么调用已有属性得到的结果是对应属性值,如果调用了对象中没有的属性,就会得到该返回值
#
#
# f = Foo('aaa')
# print(f.__dict__)
# print(f.name)
# f.age = 19      # 触发__setattr__的执行
# print(f.age)    # 触发__getattr__的执行
# object.__setattr__(f, '_Foo__size', 20)
# # print(f.size)     # 对象中没有属性,会报错
# print(f._Foo__size)
# print(f.xxx)


# # 在不继承字典的情况下,支持通过[]来赋值和取值
# class Bar:
#     def __setitem__(self, key, value):
#         setattr(self,key,value)
#         # 或 object.__setattr__(self, key, value)
#
#     def __getitem__(self, item):
#         return getattr(self, item)
#
# b = Bar()
# b.name = 'bbb'
# print(b.name)
# b['age'] = 20
# # b.age = 20
# print(b.age)


# __str__
# class Student:
#     def __init__(self, name, age):
#         self.name = name
#         self.age = age
#
#     # 定义对象的字符串表示
#     def __str__(self):
#         return self.name
#
#
# s1 = Student('张三', 29)
# print(s1.name)
# print(s1.age)
# print(s1)                   # 会调用s1的__str__方法,若没有重写__str__则输出对象的地址
#
# __repr__
# 在python解释器环境下,会默认显示对象的repr表示。
# >>> class Student:
# ...     def __init__(self, name, age):
# ...         self.name = name
# ...         self.age = age
# ...     def __repr__(self):
# ...         return self.name
# ...
# >>> s1 = Student('张三', 24)
# >>> s1
# 总结:
# str函数或者print函数调用的是obj.__str__(),repr函数或者交互式解释器调用的是obj.__repr__()
# 注意:
# 如果__str__没有被定义,那么就会使用__repr__来代替输出。
# __str__和__repr__方法的返回值都必须是字符串。


# __slots__
# 当一个类设置了__slots__属性后,这个类的__dict__属性就不存在了(同理,该类的实例也不存在__dict__属性),如此一来,设置了__slots__属性的类的属性,只能是预先设定好的。
# 当你定义__slots__后,__slots__就会为实例使用一种更加紧凑的内部表示。实例通过一个很小的固定大小的小型数组来构建的,而不是为每个实例都定义一个__dict__字典,在__slots__中列出的属性名在内部被映射到这个数组的特定索引上。使用__slots__带来的副作用是我们没有办法给实例添加任何新的属性了。
# 注意:
# 尽管__slots__看起来是个非常有用的特性,但是除非你十分确切的知道要使用它,否则尽量不要使用它。比如定义了__slots__属性的类就不支持多继承。__slots__通常都是作为一种优化工具来使用。
#
# class A:
#     __slots__ = ['name', 'age']         # 对象中只能拥有name和age属性
#
#
# a1 = A()
# # print(a1.__dict__)  # AttributeError: 'A' object has no attribute '__dict__'
# a1.name = '张三'
# a1.age = 24
# # a1.hobby = 'play'  # AttributeError: 'A' object has no attribute 'hobby'
# print(a1.__slots__)


# __call__
# class Person:
#     def __init__(self, name, age):
#         self.name = name
#         self.age = age
#
#     def __call__(self, *args, **kwargs):
#         print('调用对象的__call__方法')
#
#
# a = Person('张三', 24)        # Person也是对象,加括号触发元类的__call__
# a()                          # __call__方法使对象加括号可被调用


# __doc__
# 定义类的描述信息。注意该信息无法被继承。
# class A:
#     """我是A类的描述信息"""
#     pass
#
# print(A.__doc__)


# __eq__    拥有__eq__方法的对象支持相等的比较操作
# class A:
#     def __init__(self,x,y):
#         self.x = x
#         self.y = y
#
#     def __eq__(self,obj):           # a=>self,b=>obj
#         # 打印出比较的第二个对象的x值
#         print(obj.x)
#         if self.x +self.y == obj.x+obj.y:
#             return True
#         else:
#             return False
#
# a = A(1,2)
# b = A(2,1)
# print(a == b)


# type 和 object 的关系
# type类,继承object,是所有类的类,包括自己
# object类:谁都没继承,它是由type实例化得到的,是所有类的父类,包括type(但不包括object)

 

posted @ 2020-09-06 21:24  板鸭没有腿  阅读(130)  评论(0)    收藏  举报