python的自省
什么是自省
在计算机编程中,自省是指这种能力:检查某些事物以确定它是什么、它知道什么以及它能做什 么。自省向程序员提供了极大的灵活性和控制力。
有时我们要访问某个变量或是方法时并不知道到底有没有这个变量或方法,所以就要做些判断。判断是否存在字符串对应的变量及方法。
我们知道访问变量时是不能加引号的,否则会被当成字符串处理。如果要通过字符串找到对应的变 量,那该怎么办呢
自省的四种方法
getattr(obj, 'name'): 获取成员
根据字符串去获取obj对象里的对应的方法的内存地址
hasattr(obj, 'name'): 检查是否含有成员
判断一个对象obj里是否有对应的name_str字符串的方法 •
import sc #同文件夹下创建的一个.py文件
#python的自省
#xx.xx的形式都能自省出来
print(hasattr(sc,'a')) #判断sc里有没有a属性,为True表示有属性,为False表示没有,这里的sc是个模块
print(hasattr(sc,'b'))
print(getattr(sc,'a')) #获取sc里面的属性a
print(setattr(sc,'b','scbbbb')) #设置sc里面的属性,b为scbbbb,返回值为None
print(getattr(sc,'b'))
print(delattr(sc,'b')) #删除属性,返回值为None
print(hasattr(sc,'b'))
print(sc.a)
#接受用户从键盘的输入,可以无心啊输入按Q推出
#如果输入了func1 ,就输出func1
#其他情况,重新输入
class A:
def func1(self):
print("i am func1")
def func2(self):
print("i am func2")
a = A()
while True:
choose = input("please input function:")
if choose.lower() == 'q':
break
elif hasattr(a,choose):
getattr(a,choose)()
else:
print("没有这个函数")
if hasattr(result,'__call__'):
#判断是函数还是属性,看'__call__'函数都有__call__,没有就不是函数
#callable(result)
元类
定义
元类一般用来拦截类的创建
-
类也是对象
-
Python中一切皆对象, 包括函数和类。这意味着函数与类都可以作为参数提供、以类实例的成员 形式存在 ,且可以完成其他对象所能完成的工作
-
对象在实例化的过程中,会调用init和new方法创建新对象, 该过程对于类而言也不例 外。一个类本身又是另一个类的实例,用于创建类的类。负责生成其他类的类就是元类 (Metaclass)
-
元类就是用来创建类的类
type创建类语法
语法: type(类名, 父类的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))
#第一个参数:类名 #第二个参数:继承关系,需要元组 #第三个参数:设置属性和方法,得到字典
创建类:
MyClass = type('MyClass' , (), {})
函数type实际上是一个元类, type就是Python在背后用来创建所有类的元类(类工厂) 如:1 -> int -> type
type就是Python的内建元类,我们也可以创建自己的元类。
class Animal():
def __init__(self,name):
self.name = name
def eat(self):
print("i am eating.....")
#怎么使用type创建和上面一样的类
def init(self,name):
self.name = name
def eat(self):
print("i am eating...")
Animal = type("Animal",(object,),{"__init__":init,"eat":eat})
a1 = Animal("sc1")
print(a1.name)
class MyMate(type):
def __new__(cls,name,bases,attrs):
#name = A,bases = object,attrs属性,A.ufo
if "ufo" not in attrs:
raise TypeError("必须设置ufo属性")
return type.__new__(cls,name,bases,attrs)
#metaclass 指定 元类
class A(metaclass = MyMate):
ufo = 'sc'
print(A)
python面向对象关系
-
1、继承关系,oject是所有类的父类,是最顶层的类
-
2、创建关系 实例与类的关系,type是最顶层的类
抽象基类
-
定义了接口规范,子类必须实现抽象基类父类里的抽象方法
-
不能实例化
Abstract Base Class(抽象基类)
-
python中并没有提供抽象类与抽象方法,但是提供了内置模块abc(abstract base class)来模拟 实现抽象类
-
ABC,Abstract Base Class(抽象基类),主要定义了基本类和最基本的抽象方法,可以为子类 定义共有的API,不需要具体实现。
-
抽象基类提供了逻辑和实现解耦的能力,即在不同的模块中通过抽象基类来调用
-
ABC类实际上是一个元类
from abc import ABC,abstractmethod
class Animal(ABC):
#定义抽象方法
@abstractmethod
def eat (self):
pass
#这不用写任何东西,但是它的子类要实现eat这个方法也就是说,只需要定义接口规范,不需要具体实现
def drink(self):
pass
class Dog(Animal):
def eat(self):
print("dog i eating")
d1 = Dog()