第二十七天反射和面向对像中的内置函数

1.isinstance判断类和对象之间的关系如果存在类对象关系返回True否则返回False

class Person:
    def func(self):
        pass
a=Person()
b=1
print(isinstance(a,Person)) #左边对象右边类
print(isinstance(b,Person))
结果为
True
False
View Code

2。issubclass判断是否是子类和父类之间的关系:

class Person:
    def func(self):
        pass
class Son(Person):
    pass
b=Person()
print(issubclass(Son,Person)) #左边子类右边父类(超类、基类)
结果为
True
View Code

3.反射就是用字符串形式的名字去操作变量进行操作:

  3.1我们前面也学过用字符串进行变量的操作:

name=123
print(eval('name'))
结果为
123
View Code

使用这个存在安全隐患:因为这种操作是得到别人写好的代码直接执行,你也不知道别人的代码是否有代码病毒。

  3.2使用反射可以解决这一个问题,使用反射式使用一段写好的代码,然后执行里面的属性和方法。

4.反射类里面的属性

class Person:
    def func(self):
        print('哈哈哈')
a=Person()#实例化
a.name='alex'#给对象中添加一个元素
Person.name='123'
ret=getattr(a,'name')
print(ret)
print(a.__dict__)#显示对象中所有的属性信息并以字典的形式返回
print(Person.__dict__)
结果为
alex
{'name': 'alex'}
{'__module__': '__main__', 'func': <function Person.func at 0x0000024D5EFF5730>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None, 'name': '123'}
View Code

5.反射使用类里面的方法:

class Person:
    def func(self):
        print('哈哈哈')
a=Person()#实例化
a.name='alex'#给对象中添加一个元素
ret=getattr(a,'func')  #这一步得到方法的地址(和函数差不多)
ret()
结果为
哈哈哈
View Code

6那么反射有什么用:简单小例子用户通过输入想要查看某个对象的属性:

class Person:
    def func(self):
        print('哈哈哈')
a=Person()#实例化
a.name='alex'#给对象中添加一个元素
a.age=16
name=input('输入你想查看的属性;')
ret=getattr(a,name)
print(ret)
结果为
输入你想查看的属性;name
alex
View Code

  还有一种方法也是可以通过字符串得到类中的属性:

class Person:
    def func(self):
        print('哈哈哈')
a=Person()#实例化
a.name='alex'#给对象中添加一个元素
a.age=16
name=input('输入你想查看的属性;')
ret=a.__dict__[name]
print(ret)
结果为
输入你想查看的属性;name
alex
View Code

7但是这种方法没有办法得到类中的方法,还是只能使用反射:

class Person:
    __key=123
    @staticmethod
    def func():
        print('哈哈哈')
    @classmethod
    def func1(cls):
       return cls.__key

a=Person()#实例化
a.name='alex'#给对象中添加一个元素
a.age=16
name=input('输入你像调用的方法;')
ret=getattr(Person,name)
ret()
结果为
输入你像调用的方法;func
哈哈哈
View Code

  还有一中使用反射得到方法的使用方法:

class Person:
    __key=123
    @staticmethod
    def func():
        print('哈哈哈')
    @classmethod
    def func1(cls):
       return cls.__key

a=Person()#实例化
a.name='alex'#给对象中添加一个元素
a.age=16
name=input('输入你像调用的方法;')
print(getattr(Person,name)())
结果为
输入你像调用的方法;func1
123
View Code

8.模块里的反射方法:

import mile  #调用mile模块
print(getattr(mile,'day'))  #使用模块中day的属性
结果为
123
View Code

9.调用模块中的方法:

import mile  #调用mile模块
print(getattr(mile,'day'))  #使用模块中day的属性
getattr(mile,'func')()  #调用模块中func方法
结果为
123
哇哈哈
View Code

10内置模块也可以使用反射方法:

import time
print((getattr(time,'time'))())
结果为
1582943294.4412374
View Code

11.为什么random就不能使用getattr

import random
print(getattr(random,'randint(1,10))'))
结果为
Traceback (most recent call last):
  File "D:/python练习程序/第二十七天/practise.py", line 48, in <module>
    print(getattr(random,'randint(1,10))'))
AttributeError: module 'random' has no attribute 'randint(1,10))
View Code
import  random
print(getattr(random,'randint')(1,10))
结果为
6
View Code

12.那么python中是否可以反射自己的模块:

year=2020
import sys
name=input('请输入>>>')
print(getattr(sys.modules[__name__],name))

结果为
请输入>>>year
2020
View Code

13要反射函数怎么办:

import time
print(time.strftime('%Y-%m-%d %H:%M:%S'))
print(getattr(time,'strftime')('%Y-%m-%d %H:%M:%S'))
结果为
2020-02-29 10:49:45
2020-02-29 10:49:45
View Code

14.有时候我在在使用getattr时如果没有会报错:

import time
getattr(time,'fjdfj')
结果为
Traceback (most recent call last):
  File "D:/python练习程序/第二十七天/practise.py", line 55, in <module>
    getattr(time,'fjdfj')
AttributeError: module 'time' has no attribute 'fjdfj'
View Code

  怎么解决报错的问题:

import time
if hasattr(time,'fjdfj'): #如果为真执行下面如果为假不执行
    getattr(time,'fjdfj')#两个括号里要写的一致
else:
    print('上面的指令有误')
结果为
上面的指令有误
View Code

15对类的变量进行设置修改:

class A:
    def func(self):
        print('修改成功')
a=A()
a.name='alex'
print(a.name)
print(a.func())
setattr(a,'name','subin') #对属性进行修改
print(a.name)
setattr(a,'func','func1') #无法对方法进行修改
print(a.func1())
结果为
  File "D:/python练习程序/第二十七天/practise.py", line 69, in <module>
alex
    print(a.func1())
AttributeError: 'A' object has no attribute 'func1'
修改成功
None
subin
View Code
class A:
    def func(self):
        print('修改成功')
a=A()
a.name='alex'
print(a.name)
print(a.func())
delattr(a,'name') #对属性进行修改
print(a.name)

结果为
Traceback (most recent call last):
  File "D:/python练习程序/第二十七天/practise.py", line 78, in <module>
    print(a.name)
AttributeError: 'A' object has no attribute 'name'
alex
修改成功
None
View Code

 16.内置函数和内置方法之间有着千丝万缕的关系:

17.__str__方法:

class A:
    pass
a=A()
print(str(a))  #object里面有一个__str__方法,一但被调用,就返回这个方法对象的
                #内存地址
结果为
<__main__.A object at 0x000001BCFA6FB080>
View Code

 18.

class A:
    def __str__(self):
       return '执行了str功能'
a=A()
print(a)  #打印一个对象的时候就会调用a.__str__先从自己这里找如果没有再去找父类

结果为
执行了str功能
View Code

19.

l=[1,5,6]#进行实例化
print(l)
View Code

显示这个原因是找到列表中的__str__方法如果找不到就是用备胎:__repr__

 

 20在python中只要使用了str、%s、print都是要调用__str__方法:

class A:
    def __str__(self):
       return '执行了str功能'
a=A()  #进行实例化
print(a)  #打印一个对象的时候就会调用a.__str__先从自己这里找如果没有再去找父类
print('%s'%a)
结果为
执行了str功能
执行了str功能
View Code

21。__repr__方法:(使用repr和%都调用,如果调用str时没有也会调用这一个)(repr是str的备胎,但是str不是repr的备胎)

class A:
    def __str__(self):
       return '执行了str功能'
    def __repr__(self):
        return '执行里repr功能'
a=A()  #进行实例化
print(repr(a))
print('%r'%a)
结果为
执行里repr功能
执行里repr功能
View Code
class A:
    def __repr__(self):
        return '执行里repr功能'
a=A()  #进行实例化
print(a)  #如果没有str,可以调用__repr__
print('%r'%a)
结果为
执行里repr功能
执行里repr功能
View Code

22.总结;print(obj)、%s、str(obj)实际上就是调用了obj.__str__方法,如果str有方法,就返回的是一个字符串入股没有__str__方法,就会找本类中的__repr__方法,在没有才会去找

父类中的__str__方法

23:内置方法很多但并不是所有的内置方法都有内置函数:

class A:
    def __repr__(self):
        return '执行里repr功能'
a=A()  #进行实例化
print(len(a))
结果为
  File "D:/python练习程序/第二十七天/practise.py", line 93, in <module>
    print(len(a))
TypeError: object of type 'A' has no len
View Code

24.

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

    def __len__(self):
        return len(self.student)
a=A('jfkdj')  #进行实例化
a.student.append('天逛')
a.student.append('西斯')
print(len(a))
结果为
2
View Code

25.__del__方法:

  析构方法:当对象在内存中被释放时,自动触发执行。此方法无需定义,因为python是一门高级语言,程序元在使用时无需关心内存的释放和分配,这种工作基本上交给ptyhon解释

来执行,所以析构的调用是由解释器进行垃圾的回收时自动执行触发的

class A:
    def __del__(self):
        print('执行我了:')
a=A()
print(a)
del a
print(a)


结果为
<__main__.A object at 0x0000024E10C6B080>
Traceback (most recent call last):
  File "D:/python练习程序/第二十七天/practise.py", line 96, in <module>
    print(a)
NameError: name 'a' is not defined
执行我了:
View Code

26当一个指令执行结束以后就会执行此语句:

class A:
    def __del__(self):
        print('执行我了:')
a=A()
import time
time.sleep(2)#当这个程序执行结束之后python内部会把这个内存进行回收即执行del
结果为
执行我了:
View Code
class A:
    def __del__(self):
       self.close()#执行此语句的时候就会把文件进行关闭了
a=A()
a.f=open()
del a.f #这样虽然会把文件删了但是内存还在占用使用del限制性def的del在执行内部del

结果为
View Code

27.内置call方法的使用:

class A:
    def __call__(self):
       print('执行内部的call方法了')
a=A()()#在对象后面加括号就是执行call方法:
b=A()
b()
结果为
执行内部的call方法了
执行内部的call方法了
View Code

 

posted @ 2020-02-29 11:15  chown  阅读(114)  评论(0编辑  收藏  举报