反射

动态语言:是指不事先规定变量的数据类型,在程序运行到变量所在的赋值语句时,才知道变量的类型

用处:别的程序传来的变量名,不知道它是什么类型,就不知道它有哪些属性和方法

实现反射机制的步骤:

1.通过dir()查看一个对象下的所有属性

​ dir(obj) #获取对象的所有属性名,返回属性名的字符串列表

2.通过字符串反射到真正的属性上,得到属性值

使用以下四个内置函数,可以通过字符串来操作属性值


hasattr(obj,'name')   #判断一个对象是否有某个属性
getattr(obj,'name')   #获取一个对象的某个属性值
getattr(obj,'name',None)   #获取一个对象的某个属性值,如果obj没有name这个属性,就返回None

setattr(obj,'name',egon)   #设置一个对象的某个属性值
delattr(obj,'name')   #删除一个对象的某个属性

class Ftp:
    def put(self):
        print('正在执行上传功能')

    def get(self):
        print('正在执行下载功能')

    def interactive(self):
        while True:
            msg = input('请输入功能名称:').strip()

            if hasattr(self, msg):
                getattr(self, msg)()
            else:
                print('输入的指令不存在')



obj = Ftp()
obj.interactive()

内置方法:定义在类内部,以__开头,以__结尾的方法,其特点是会在某种情况下自动触发执行,一般不是给我们来调用的

用内置方法是为了高度定制化自定义的类或对象

class People():
    def __init__(self, name, age):
        self.name = name
        self.age = age
        
	#重写__str__方法,定制打印对象时,显示的内容
    def __str__(self):
        return '%s:%s' % (self.name,self.age)


obj = People('egon',18)
print(obj)
'''
egon:18
'''

class People():
    def __init__(self, name, age):
        self.name = name
        self.age = age

obj = People('egon',18)
print(obj)

'''
<__main__.People object at 0x0000000001E35EE0>
'''
print(obj)== print(obj.__str__) #打印对象obj本身,会触发obj下的__str__方法,该方法必须返回一个字符串类型的值,并将返回值打印出来
__del__ #在清理对象时(通常是在程序运行即将结束时,也有可能在程序运行过程中,自己写了:del obj 时,但很少这么做)触发该方法,先执行该方法,再清理对象
应用程序结束时,回收某个对象占用占用的资源,包括占用的的应用程序的资源以及对象的某个属性占用了操作系统的资源(比如打开文件,发起网络连接等),
占用的的应用程序的资源由应用程序自己释放
在应用程序结束之前,该方法用来告诉操作系统(即发起系统调用)可以回收有关的系统资源了
class People():
    def __init__(self, name, age):
        self.name = name
        self.age = age

        # self.x=占用的操作系统的资源


    def __del__(self):
        print('running')
        # 发起系统调用,告诉操作系统可以回收有关的系统资源了
        # self.x.close()


obj = People('egon',18)
print('end')

'''
end
running

'''
__setattr__ # 当 对象.属性=xx 赋值时触发
__getattr__	# 当 对象.属性    取值时触发
__getitem__	# 重写一个类的这个方法,可以实现:以键值(字典)的方式获取属性值
__setitem__	 # 重写一个类的这个方法,可以实现:以键值(字典)的方式为属性赋值

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

    def __setitem__(self, key, value):
        setattr(self,key,value)
        
    def __getitem__(self, item):
        return getattr(self,item)

p=Person('page')
print(p.name)
p['name']='land'
print(p.name)
print(p['name'])
'''
page
land
land
'''



class Mydic(dict):
    def __setattr__(self, key, value):
        self[key] = value

    def __getattr__(self, item):
        return self[item]


mydic = Mydic(name='page', age=18)
print(mydic.name)
'''
page
'''


class Mysql:
    # 进入with语句块时执行此方法,如果有返回值就会赋值给as声明的变量
    def __enter__(self):
        self.conn=pymysql.connect(user='root',
        password="Edwinsha2018@1",
        host='127.0.0.1',
        database='day61',port=3306)
        # return self
        return self.conn  #根据具体情况来看要返回什么

    # with语句块结束时执行此方法
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.conn.close()
        # print(1,exc_type)
        # print(2,exc_val)
        # print(3,exc_tb)


with Mysql() as conn:
# with Mysql() as mysql:
    # 查询语句
    # cursor=mysql.conn.cursor(cursor=pymysql.cursors.DictCursor)
    cursor=conn.cursor(cursor=pymysql.cursors.DictCursor)
    sql='select name,age from app01_author'
    cursor.execute(sql)
    res=cursor.fetchall()
    print(res)

'''
[{'name': 'egon', 'age': 84}, {'name': 'tank', 'age': 50}, {'name': 'jason', 'age': 18}]
'''