python 映射,动态加载模块,动态生成类


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 *的操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值