py5.30

# 类的内置方法、双下方法
#1.对象(): 触发__call__方法
#2.len(对象):触发__len__方法: return len(对象) --> 返回对象的长度
#                             return len(self.__dict__) -->返回各个属性的长度、
#3.obj1 == obj2:    触发__eq__(self,other)方法:
# class A:
#     def __init__(self,name):
#         self.name = name
#     def __eq__(self, other):
#         if type(self) == type(other)and self.name == other.name:
#             return True
#         else:return False
# obj1 = A('alex')
# obj2 = A('alex')
# print(obj1 == obj2)
#4.hash(对象)     -->触发__hash__方法。
# 去重:set(对象)-->触发__hash__方法及__eq__方法。
#100个人,实现去重。(姓名和性别一样,年龄可能会不一样)
#set()去重机制:1.首先判断hash值是否相同,同一个人,姓名性别不会变但是年龄会变,所以同一个人一般返回的都是不一样的hash值,
#                set无法去重。所以只判断姓名和性别:
#                   只返回姓名和性别字符串拼接后的hash值,如果不同则放入各自内存地址中,如果相同,继续判断。
#               2.判断姓名和性别的值是否相同,触发__eq__方法,如果相同,返回True,set实现去重,如果不同再放入各自的内存地址。
# class A:
#     def __init__(self,name,sex,age):
#         self.name = name
#         self.sex = sex
#         self.age = age
#     def __hash__(self):
#         return hash(self.name+self.sex) #只判断姓名和年龄,只返回它们的hash值。
#     def __eq__(self, other):
#         if type(self) == type(other)and self.name == other.name and self.sex == self.sex:
#             return True      #只判断姓名和年龄的值,如果再为真则返回真,去重。
#         else:return False
#
# person_list = [A('alex','male',i+1) for i in range(100)]
# print(set(person_list))
#5.print(对象名)/str(对象名)/'%s'% 对象名 :触发__str__方法:return ''.join([self.name,self.sex,str(self.age)])
#6.repr(对象名)/'%r'%对象名:触发__repr__方法:1.当__str__不在时,可以完全替代__str__。
#                                               被print(对象名)/str(对象名)/'%s'% 对象名 这些触发。
#                                             2.__str__存在时,各自执行各自的功能。
#                                             3.不可反向,__str__不能替代__repr__
# class A:
#     def __init__(self,name,age,sex):
#         self.name = name
#         self.age = age
#         self.sex = sex
    # def __str__(self):
    #     return '|'.join([self.name,str(self.age),self.sex])
#     def __repr__(self):
#         return '*'.join([self.name,str(self.age),self.sex])
# obj = A('alex',19,'男')
# print(obj)  #如果__str__不存在,则执行__repr__方法。
# print(repr(obj))

 

#反射:使用字符串形式的变量来操作变量的值
#一、getattr + hasattr
#A . B 的形式的,可以用getattr找到。
#1.用类反射,静态属性、类方法、静态方法。
# class A:
#     name = 'taibai'
#     age = 19
#     def __init__(self,sex,school):
#         self.sex = sex
#         self.school = school
#     def func(self):
#         print('我是func函数')
# print(getattr(A,'name'))    #变量名一定是字符串形式的。
#与hasattr配合使用。
# content = input('请输入您要查找的属性').strip()
# if hasattr(A,content):
#     print(getattr(A,content))
# else:
#     print('没有此属性')
#2、用对象反射, 对象属性,类中的普通方法。
# obj = A('male','oldboy')
# print(getattr(obj,'sex'))
# getattr(obj,'func')()  #调用方法,getattr得到的是方法名的内存地址,后面再加括号即可调用。
#3、用模块反射,先导入模块,然后调用其中的类、变量和方法。
# import mmm
# print(getattr(mmm,'a'))      #mmm.a
# getattr(mmm,'wahaha')        #mmm.wahaha
# getattr(getattr(mmm,'QQxing')('alex'),'ADCa')()
#4、当前模块中用反射操作全局变量。见mmm文件。
# import mmm   #执行getattr(sys.modules[__name__],'wahaha')()
             #此处的__name__由于在外面调用变成了'mmm',本文件中导入了mmm, 可以正常调用。
#一个文件调用另外一个文件(模块)的时候,模块中的sys.path和sys.modules中的_main_都会被改变成调用者的路径。
#所以在导入模块(sys.path中)和调用属性或方法(sys.modules['_main_'])时一定要写活。
#如:导入当前文件夹下的login:正常情况下直接import login就可以了,但是当被别的文件夹的文件当成模块调用时则找不到login了,
# 因为sys.path下的上级目录被改变成了调用者的上级目录。
#解决: from core.login import login
#同理,sys.modules['_main_']在被别的文件调用的时候,'__main__'对应的值也会变成调用文件的路径,找不到被调用的属性或方法了。
#解决: sys.modules[__name__]
#二、另外两个反射方法:setattr/delattr
# setattr(A,'name','alex')   #有则修改。无则添加。
# print(A.name)
# delattr(A,'name') #删除属性
# print(A.name)
反射

 

posted @ 2018-05-30 20:08  消暑酸梅粉  阅读(111)  评论(0编辑  收藏  举报