django和python中的反射(自省)--类、实例、字符串、方法之间的相互转换

目录

python

类和实例

  • 类获取实例: 实例化对象, 存在class A, 获取A的实例
# 已知类A
class A:
    def fun(self, ):
        print('Class A, fun')

# 实例化A的实例
>>> a = A()
>>> a.fun()
Class A, fun
  • 实例获取类: 已知实例a, 获取实例的类
# 已知实例a
>>> a.fun() 
Class A, fun

# 通过实例获取类
>>> A = a.__class__  # 获取类
>>> b = A()  # 用类实例化对象
>>> b.fun()  # 调用方法
Class A, fun

类和字符串

  • 类获取类名(字符串): 已知类A, 获取类名
# 已知类A
class A:
    fun(self, ):
        print('Class A, fun')

>>> name = A.__name__
>>> print(type(name), name)
<class 'str'> A
  • 字符串获取类: 已知类名,获取类对象来源参考
>>> name = 'A'

# 方法一
>>> A = eval(name) # 在字符串来源不可信的情况下, 不推荐这种方法, 因为eval会执行任意的python代码

# 方法二
>>> import sys
>>> A = getattr(sys.modules[__name__], name) # 如果获取失败会报错, 需要加上异常处理

# 方法三
>>> A = globals()[name]  # 如果获取失败会抛异常, 需要处理

>>> A
>>> a = A()
>>> a.fun()
Class A, fun

实例和字符串

  • 实例和字符串需要通过类来做中转就好了

django

django和python有一些区别, django中主要涉及 app标签,模型, 模型实例和字符串之间的转换

app标签和模型

  • 根据模型获取app_label
class ModelA(models.Model):
    pass

>>> app_label = ModelA._meta.app_label

app标签和实例

  • 根据实例获取app_label
>>> a  # 一直模型实例a
>>> app_label = a._meta.app_label

模型和字符串

根据模型获取字符串(模型名)

class ModelA(models.Model):
    pass

>>> name = ModelA.__name__
>>> name
'ModelA'
  • 根据字符串获取模型: 条件不够, 还需要app_label

模型实例和字符串

  • 根据实例获取字符串(模型名)
>>> m  # 已知模型实例
>>> name = m.__class__.__name__
>>> name
'ModelA'
  • 根据字符串获取模型: 条件不够, 还需要app_label

app标签, 模型名和模型

>>> app_label = 'blog'
>>> model_name = 'Post'
>>> from django.apps import apps

# 方法一
>>> path = '.'.join([app_label, model_name])
>>> Post = apps.get_model(path)  # 获取到模型

# 方法二
>>> Post = apps.get_model(app_label=app_label, model_name=model_name)

猜你喜欢

转载自blog.csdn.net/DrCBin/article/details/80214232