python基础(面对对象之反射)

一、issubclass 与 type与isinstance

  1.1 定义:

    isinstance:

      格式: isinstance(子类名, 父类名)

      功能:判断类与类之间是否有继承关系

    type:

      格式:type(实例对象, 类)
      功能:只承认实例化这个对象的那个类,与所有父类的其他继承类无关

    issubclass:

      格式:issubclass(类1, 类2)
      功能:判断类1是不是类2的子类

  1.2 相互关系:

  
# 示例:

class User(object): pass
class VIPUser(User): pass


alex = VIPUser()  # 实例化

ret1 = type(alex) is User
ret2 = isinstance(alex, User)
print(ret1, ret2)                     # False True

ret1 = type(alex) is VIPUser
ret2 = isinstance(alex, VIPUser)
print(ret1, ret2)                     # True True
View Code
  
# 示例:

class User(object): pass
class VIPUser(User): pass


alex = VIPUser()  # 实例化

ret = issubclass(VIPUser, User)
print(ret)   # True
View Code

二、 反射getattr

  2.1 定义:

    用字符串数据类型的变量名 找到这个变量对应的内存地址

  2.2  反射用法类型一:

    a.b结构结构型:
      用对象\类\模块反射,都只有以下场景
      a.b中b是属性或者变量值


    2.2.1 类的对象使用反射:
      obj.属性名
      obj.方法名()

  
# 示例:

# 1.使用对象反射
class Manager:  # 管理员用户
    def __init__(self, name):
        self.name = name

    def create_course(self):  # 创建课程
        print('in Manager create_course')

    def create_student(self):  # 给学生创建账号
        print('in Manager create_student')

    def show_courses(self):  # 查看所有课程
        print('in Manager show_courses')

    def show_students(self):  # 查看所有学生
        print('in Manager show_students')


alex = Manager('alex')
operate_lst = [('创建课程', 'create_course'), ('创建学生账号', 'create_student'),
               ('查看所有课程', 'show_courses'), ('查看所有学生', 'show_students')]

# 打印标题
for index, opt in enumerate(operate_lst, 1):
    print(index, opt[0])

num = input('请输入您要做的操作 :')
# 类方法的调用
if num.isdigit():
    num = int(num)
    if hasattr(alex, operate_lst[num - 1][1]):   # 判断字符串是否是存在被调用的属性与方法中
        getattr(alex, operate_lst[num - 1][1])()  # 反射
View Code

    2.2.2 在类中使用反射:

      cls.静态变量名
      cls.类方法名()
      cls.静态方法名()

  
# 示例:

class A:
    Country = '中国'

    @classmethod
    def show(cls):
        print('国家 : ', cls.Country)


# 类属性对比
print(A.Country)
print(getattr(A, 'Country'))   # print(A.Country)

# 类方法对比
A.show()
getattr(A, 'show')()   # A.show()
View Code

    2.2.3  在模块使用反射:

        模块中的方法名

  
# 示例:

import re

# 普通方法:
ret = re.findall('\d+', '2985urowhn0857023u9t4')
print(ret)  # ['2985', '0857023', '9', '4']
# 反射方法:
ret = getattr(re, 'findall')('\d+', '2985urowhn0857023u9t4')
print(ret)   # ['2985', '0857023', '9', '4']
View Code

  2.3  反射用法类型二:

    如果是本文件中的内容,不符合a.b这种结构时,反射的用法:

      1、直接调用func()
        getattr(sys.modules[__name__],'func')() # sys.modules[__name__] 当前文件
      2、直接使用类名 Person()
        getattr(sys.modules[__name__],'Person')()
      3、直接使用变量名 print(a)
        getattr(sys.modules[__name__],'a')

    2.3.1  变量名使用反射:

  
# 示例:

from sys import modules

a = 1
b = 2

print(a)
ret = getattr(modules[__name__], 'a')   # print(a)
print(ret)
View Code

    2.3.2  函数名使用反射:

  
# 示例:

from sys import modules

def func(a,b):
    print('in func', a, b)


func(1, 2)
getattr(modules[__name__], 'func')(1, 2)   # func
View Code

    2.3.3  类名使用反射:

  
# 示例:

from sys import modules

class Course:
    def func(self):
        print('in func')


print(Course)
print(getattr(modules[__name__], 'Course'))   # Course
getattr(modules[__name__], 'Course')()   # 实例化的过程
View Code

三、sys模块中modules的用法

  定义:查看系统所有模块,以字典形式存在,key是模块的名字,value则是模块对应的文件地址

  
# 示例:

from sys import modules

print(modules)    # dict KEY是模块的名字,value就是这个模块对应的文件地址


# modules应用:
import re
print(re)                 # <module 're' from 'D:\\Program Files\\Python36\\lib\\re.py'>
print(modules['re'])      # <module 're' from 'D:\\Program Files\\Python36\\lib\\re.py'>

print(re.findall)             # <function findall at 0x0000022D004C7EA0>
print(modules['re'].findall)  # <function findall at 0x0000022D004C7EA0>
View Code

四、hasattr用法

  定义:判断字符串变量是否存在类中,存在则为True,否则为False

  
# 示例:

class A:
    def __init__(self, name):
        self.name = name

    def func(self):
        print('in func')

a = A('123')

while True:
    name = input('>>>')
    if hasattr(a, name):  # 判断字符串变量是否存在类中
        func_attr = getattr(a, name)
        if callable(func_attr):  # 判断字符串是否可以调用(调用:方法, 不可调用:属性)
            func_attr()
        else:
            print(func_attr)
View Code

五、setattr用法

  定义:能够通过字符串数据类型的变量名 给一个对象修改或者添加属性\变量,不能用来处理函数或者是其他方法

  
# 示例:

class A:
    def func(self):
        print('in func')

a = A()
a.name = '123'
print(a.name)   # 123

# 通过setattr给类A增加一个name属性(a.name = 123)
setattr(a, 'name', '123')   # a.name = 123
print(a.name)   # 123
View Code

六、delattr用法    

  定义:只用来删除 属性\变量

  
# 示例:

class A:
    def __init__(self, name):
        self.name = name

    def func(self):
        print('in func')

a = A('123')

# del a.b 删除属性  相当于删除了a对象当中的b属性
del a.name
delattr(a, 'name')  # 删除属性
View Code

七、 反射getattr补充

  getattr方法后面可以指定参数:

  如果变量存在,则获取到变量的值,否则返回指定的参数

class AB(object):
    count = 10


def test():
   #print(getattr(AB, "count", None)) #10
print(getattr(AB, "counter", None)) #None if __name__ == '__main__': test() 打印结果: None

 

posted @ 2019-04-01 20:01  Amorphous  阅读(149)  评论(0编辑  收藏  举报