巨蟒python全栈开发-第19天 核能来袭-反射

一.今日主要内容

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__
原文地址:https://www.cnblogs.com/studybrother/p/10151144.html