一.今日主要内容
1.isinstance,type,issubclass
A.isinstance: 判断你给对象是否是xx类型的. (向上判断)
B.type: 返回xxx对象的数据类型
C.issubclass: 判断xxx类是否xxx的子类
(1)day11介绍过是否是可迭代的和是否是迭代器
(2)issubclass( 判断类是否为某类的子类//查看某一个类是否为另一个类的派生类 )
(3)isinstance (对象;判断类型)
(4)type:类型
2.如何区分方法和函数(代码)
在类中:
实例方法:
如果是类名.方法 函数
如果是对象.方法 方法
类方法:都是方法
静态方法:都是函数
from types import MethodType, FunctionType
isinstance()
3.反射(重要)
一共就4个函数(在,每一道例题中,体会,到底是怎么用的)
高手和水平差一点的人,就在于经验的掌控,这就要平时多留意生活的细节,生活会眷顾有心人,多次揣摩必有所得
attr:attrbute属性
getattr()
从xxx对象中获取到xxx属性值
hasattr()
判断xxx对象中是否有xxx属性值
delattr()
从xxx对象中删除xxx属性
setattr()
设置xxx对象中的xxx属性为xxx值
二.今日内容大纲
1.isinstance&type&issubclass
2.区分方法和函数
3.反射
三.今日内容详解:
1.isinstance&type&issubclass
2.区分方法和函数
3.反射
作业:
(1)类变量和示例变量的区别?
答案:类变量是属于类的
示例变量是属于实例变量的,示例变量是属于对象的
(3)isinstance和type的区别并用代码举例说明?
isinstance: 判断xxx是否是xxx类型的(向上判断) type 返回xx对象的数据类型 ''' #自己总结 (1)注意两者的写法是有区别的 (2)A:type()不会认为子类是一种父类类型,不考虑继承关系 B:isinstance() 会认为子类是一种父类类型,考虑继承关系 示例: class Animal: def eat(self): print('刚睡醒吃点儿东西') class Cat(Animal): def play(self): print('猫喜欢玩儿') c=Cat() print(isinstance(c,Cat)) # True c是一只猫 print(isinstance(c,Animal)) # True print(type(c)==Cat) print(type(c)==Animal) print(type(c)) #<class '__main__.Cat'> '''
(4)
这个题目需要认真反复研究
题目:补全代码
def func(arg):
"""
判断arg是否可以被调用,如果可以则执行并打印其返回值,
否则直接打印结果
:param arg:传入的参数
arg:
"""
pass
def func(arg): if callable(arg): #判断xxx是否可以被调用 () print(arg()) else: print('不可以被调用') # func(1) #结果执行1() 不可以被调用 def haha(): print('呵呵') return '吼吼' func(haha) #最后执行的是 :打印'呵呵',因为打印了arg(),所有结果就有了两个. # 结果: # 呵呵 # 吼吼 思考问题: 对象可不可以被调用?只要类中有__call__,对象就是可以被调用的
(5)
补全代码(重点题目)
def func(*args):
"""
计算args中函数\方法\ Foo类对象的个数,并返回给调用者
:param args:传入的参数
"""
pass
from types import FunctionType,MethodType class Foo: def chi(self): print('我是吃') @staticmethod def he(): print('我是he') def func(*args): #*args可能包含:方法,函数,Foo类对象 hanshu=0 fangfa=0 foo=0 for el in args: #循环完成之后打印 if isinstance(el,FunctionType): #函数 hanshu+=1 elif isinstance(el,MethodType): #方法 fangfa+=1 elif type(el)==Foo: foo+=1 print(hanshu,fangfa,foo) f1=Foo() f2=Foo() func(f1,f1,f1,f2,f2,f2,f1.chi,f1.he,Foo.chi,Foo.he) #6个对象,1个方法,3个函数 print(Foo) #打印类名 f=Foo() print(type(f)) #type打印的类
'''
结果:
3 1 6
<class '__main__.Foo'>
<class '__main__.Foo'>
'''
!!!!!!type拿到的就是类!!!!!!
有些东西真的是需要重复记忆的
(6)
class StarkConfig(object): list_display=[] #类变量是共享出去的 def get_list_display(self): self.list_display.insert(0,33) return self.list_display class RoleConfig(StarkConfig): list_display=[11,22] s1=StarkConfig() s2=StarkConfig() result1=s1.get_list_display() print(result1) result2=s2.get_list_display() print(result2) print(result1 is result2) print(s1.list_display) ''' 结果: [33] [33, 33] True [33, 33] ''' #最后的result1和result2的内存地址是一样的,所以显示True #要想自己创建自己的
(7)
class StarkConfig(object): list_display=[] def get_list_display(self): self.list_display.insert(0,33) return self.list_display class RoleConfig(StarkConfig): list_display = [11,22] s1=StarkConfig() s2=RoleConfig() result1=s1.get_list_display() print(result1) result2=s2.get_list_display() print(result2) #看下内存地址 print(result1 is result2) print(id(result1)) print(id(result2)) 结果: [33] [33, 11, 22] False 1762754727304 1762754727688
(8)
class StarkConfig(object): list_display=[] def get_list_display(self): self.list_display.insert(0,33) return self.list_display class RoleConfig(StarkConfig): list_display=[11,22] s1=RoleConfig() s2=RoleConfig() result1=s1.get_list_display() print(result1) result2=s2.get_list_display() print(result2) 结果: 分析同第六题的继承 #用的是同一份类变量 结果: [33, 11, 22] [33, 33, 11, 22]
(9)
class Base(object): pass class Foo(Base): pass print(issubclass(Base,Foo)) #结果:False
(11)#重点题目,这是一道综合的大题(有必要,反复看,手写多遍)
#要求:
如果有以下handler.py文件,请run.py中补充代码实现:
获取handler中所有成员名称:dir(handler)
获取handler中名字叫Base的成员
检查其他成员是否是Base类的子类(不包含Base),如果是则创建对象并添加到objs列表中
# #原例 # handler.py文件内的内容 class Base(object): pass class F1(Base): pass class F2(Base): pass class F3(F2): pass class F4(Base): pass class F5(object): pass class F6(F5): # pass #run,py import handler def func(): objs=[] name_list=dir(handler) #简介:查看xx对象中的所有的内容,迭代器中用过 print(name_list) if __name__== '__main__': func() #自己测试的程序 import handler def func(): objs=[] name_list=dir(handler) #简介:查看xx对象中的所有的内容,迭代器中用过 print(name_list) # print(dir(handler)) #整合,上边的两行 if __name__== '__main__': func() # 理解的知识点 # print(help(dir())) #builtins 内置函数 #老师讲解:#(重点题目,需要反复理解issubclass,type,isinstance) import handler def func(): objs=[] name_list=dir(handler) #简介:查看xx对象中的所有的内容,迭代器中用过 print(name_list) ''' #结果是: ['Base', 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__'] ''' base=getattr(handler,'Base') #拿到Base类 print(base) ''' #结果是: <class 'handler.Base'> ''' for el in name_list: #从模块中的所有的名字中拿到每一个名字 if not el.startswith('__')and issubclass(getattr(handler,el),base)and el!='Base': #不是父类本身;不是以__开头的;是base的子类,通过得到每一个类名;三个条件的交集 #双下划线开头和结束的是模块 #getattr(handler,el)得到模块里边的类名 objs.append(getattr(handler,el)()) #因为要放的是对象,所以要加上括号 print(objs) # print(name_list) # print(dir(handler)) #整合 if __name__== '__main__': func() ''' getattr():从xxx对象中获取到xxx属性值 本题是:getattr(handler,el)得到模块里边的类名 '''
(12)
#没有思路,老师当时漏掉的小知识点 class Foo(object): def __init__(self): self.name = ' ' self.age=100 obj=Foo() setattr(obj,'email','wupeiqi@xx.com') # #请实现:一行代码实现获取obj中所有成员(字典类型) # # #老师讲解: # # 如何拿到对象中所有的成员 print(obj.__dict__) #一句话拿到一个字典 # # 结果:{'name': ' ', 'age': 100, 'email': 'wupeiqi@xx.com'}
(13)
class Foo(object): def __init__(self): self.name=' ' self.age=100 obj=Foo() setattr(Foo,'email','wupeiqi@xx.com') #必须在Foo中加上这个信息,在对象中加会产生 # type object 'Foo' has no attribute 'email' v1=getattr(obj,'email') v2=getattr(Foo,'email') print(v1,v2) #类和对象都有 ''' wupeiqi@xx.com wupeiqi@xx.com ''' #总结:从类和对象都可以拿到属性
(14)什么是可迭代对象?如何将一个对象变成可迭代对象?
# A. class Foo: #类是不可迭代的 pass #'Foo' object is not iterable f=Foo() for e in f: print(e) #B. 将类变成可迭代的 class Foo: def __iter__(self): return (i for i in range(10)) #生成器表达式 f=Foo() for e in f: print(e) ''' 结果: 0 1 2 3 4 5 6 7 8 9 '''
(15)
15.如何让一个对象可以被执行? 在类中添加 __call__