class Person():
def __init__(self, name, age):
self.name = name
self.age = age
def walk(self):
print( "walking")
p = Person("Alex", 22)
# 反射、映射、自省
# getattr() # 获取 (实例对象\类,字符串-可以是属性或方法,[没有的话返回的值]) --> 如果是属性则返回值,如果是方法则返回函数,可以用a(实例对象/类) 来调用
# a = getattr(Person,"walk",'pip')
# a(Person) # -->walking
# a(p) # -->walking
#
# a = getattr(p,"walk",'pip')
# a() # -->walking
# hasatter() # 判断是否存在 (实例对象\类,字符串-可以是属性或方法) 判断这个类或者实例对象中是否有该属性或者方法
# print(hasattr(p,"name")) #-->True
# print(hasattr(p,"walk")) #--> True
# print(hasattr(Person,"name")) #-->Fales
# print(hasattr(Person,"walk")) #--> True
# setattr() #赋值(实例对象\类,字符串-可以是属性或方法,属性的话属性的值/方法的话就是一个函数名(方法名,有self))
## static 属性
# setattr(p,"sex", "Male")
# print(p.sex) # --> Male
#
# setattr(Person,"sex", "Female")
# print(p.sex) # --> Male
# print(Person.sex) # --> Female
# p1 = Person("a",10)
# print(p1.sex) # --> Female
# 方法
# def talk1(self):
# print(self.name, "is talking1....")
# def talk(self):
# print(self.name, "is talking....")
# setattr(p,"speak1",talk1)
# p.speak1(p) # -->Alex is talking1....
# Person.speak1() # 报错,没有speak1
# setattr(Person,"speak",talk)
# p.speak() # --> Alex is talking1....
# Person.speak(p) # --> Alex is talking....
# delattr() # 删除 等价于del
# delattr(p,"name") #等价于del p.name
# # print(p.name) # -->'Person' object has no attribute 'name'
# print(p.age) #-->22
# p1 = Person("a",10)
# print(p1.name) #-->a
# delattr(Person,"walk") # 对于类,只能删除方法,不能删除init中的属性
# # print(p.name) # -->'Person' object has no attribute 'name'
# print(p.age) #-->22
# p1 = Person("a",10)
# # print(p1.name) #-->a
# print(p1.age) #-->22
# p1.walk()
#
# # __name__ : 在当前模块下主动执行的情况下(不是被导入执行的),为 __main__
# # 在被其他模块导入执行的情况下,为模块名
#
# if __name__ == "__main__":
# print("是主动执行,不是被导入后执行的")
import test_import
if hasattr(test_import,"Animal"):
f = getattr(test_import,"Animal")
print(f) #--><class 'test_import.Animal'>
k = f("a1")
print(k.name) # -- > a1
k.introduce() # --> 123
动态加载模块
# __import__("test") # 解释器使用
# 官方推荐
# import importlib
# importlib.import_module("animal.dog") # 使用字符串,同级目录下的可以直接文件名.模块名(py文件名)
动态生成类
class Person():
def __init__(self, name, age):
self.name = name
self.age = age
p = Person("Alex", 22)
print(type(p)) # -- > <class '__main__.Person'> 这是一个Person类
print(type(Person)) #-- > <class 'type'> 实质是type
print(p) #-- > <__main__.Person object at 0x000000DBD25B2278>
print(Person) # -- > <class '__main__.Person'>
# 可以使用type 来动态加载类
def __init__(self, name, age):
self.name = name
self.age = age
dog_class = type("Dog",(object,),{"role":"dog","__init__":__init__})
print(dog_class) # -- > <class '__main__.Dog'> 生成了一个名为Dog 的类
d = dog_class("dog1",2)
print(d.role,d.name,d.age) # -- > dog dog1 2
# d2 = Dog("dog2",3) # 报错(name 'Dog' is not defined) 不能用类名实例化,需要用赋值的变量名 dog_class 实例化
# print(d2.role,d2.name,d2.age)
print(d) # -- > <__main__.Dog object at 0x000000DF14A72C50>
print(dog_class) # -- > <class '__main__.Dog'> 实际类名还是Dog ,但是实例化的时候需要用变量名 dog_class
# print(Dog) # 报错(name 'Dog' is not defined) 没有Dog
print(type(d)) # -- > <class '__main__.Dog'>
print(type(dog_class)) # -- > <class 'type'>
自定义异常
class MyException(BaseException):
def __init__(self, msg):
self.message = msg
def __str__(self):
return self.message
try:
raise MyException("自定义错误") # 主动触发异常
except MyException as e :
print(e)
断言 : assert 判断代码是否符合预期
assert 1+1 == 2
assert 1 + 1 == 3 #报 AssertionError 错
动态加载目录下所有的类
使用pkgutil,内置的方法,常用的话有两个方法
iter_modules(path=None, prefix='')
#Yields (module_loader, name, ispkg) for all submodules on path, or, if path is None, all top-level modules on sys.path.
path是包的目录路径,prefix是输出时,所有包的名字的前缀。用来获取该path下的子模块或子包。
walk_packages(path=None, prefix='', onerror=None)
#Yields (module_loader, name, ispkg) for all modules recursively on path, or, if path is None, all accessible modules.
同上,但是这个方法是递归获取路径下的所有模块。
具体使用如下:
- 动态加载modelsql中所有类
for importer_sql, modname, ispkg_sql in pkgutil.walk_packages(path=modelsql.__path__,
prefix=modelsql.__name__+'.',
onerror=lambda x: None):
exec('from ' + modname + ' import *')
相当于对目录下所有的类执行了import *的操作