您的位置:首页 > 编程语言 > Python开发

【原创】Python 反射 ex…

2017-03-20 14:45 344 查看
很多时候,要想多可配置、可扩展的程序,反射用到的实在有点多。也可能使我认知有限,但是暂时也只能这么想,有好的想法邮箱我~~qq1126918258@gmail.com

看看我以前的实现方法。。

class Reflector(object):
    """
   
因为根据类名实例化一个类,需要重新import,底层yzs_utils无法import app应用层file.
   
所以暂时实现为:判断一个类的实例,是否为另一个类的子类。
    """

    def __init__(self,
class_name=None, parent_class=None):
     
  """
     
  输入一个类的实例,以及一个父类类型,如果这个类是父类的子类,返回这个子类对应的实例.
     
  如果参数不对,返回None;
     
  如果非父类的子类,返回False
     
  :param class_name: class name, type:实例.
     
  :param parent_class: parent class, type: class
object.
     
  :rtype : return class
object,如果class_name对应的类,是类(parent_class)的子类,返回该类。
     
  """
     
  if parent_class:
     
     
self.parent_class = parent_class
     
      if
class_name:
     
     
    self.class_name =
class_name
     
     
    # return
self.create_object(class_name, parent_class)

    def create_object(self,
class_name=None, parent_class=None):
     
  """
     
  输入一个类的实例,以及一个父类类型,如果这个类是父类的子类,返回这个子类对应的实例.
     
  如果参数不对,返回None;
     
  如果非父类的子类,返回False
     
  :param class_name:class name, type:实例.
     
  :param parent_class:parent class, type: class
object.
     
  :rtype : return class
object,如果class_name对应的类,是类(parent_class)的子类,返回该类。
     
  """
     
  # pass
     
  if not parent_class and not self.parent_class:
return None
     
  if not class_name and not self.class_name:
return None
     
  if not parent_class: parent_class =
self.parent_class
     
  if not class_name: class_name =
self.class_name
     
  if isinstance(class_name, parent_class):
     
      # return
class_name
     
      return
True
     
  return False

def test():
    class A(object):
     
  def __int__(self):
     
      self.name
= 'A'

    class t_a(A):
     
  def __init__(self):
     
      self.name
= "a"

    class t_b(A):
     
  def __init__(self):
     
      self.name
= "a"

    a_cls = t_a
    test_r =
Reflector(a_cls(), A)
    ob =
test_r.create_object()

    print ob
    print

if __name__ == "__main__":
    test()

这种方法,怎么用呢。。
module_class = None

module = __import__("crawler.data_transformers.%s" %
module_name,globals(), locals(), [module_class_name])
str_exec = "module_class = module.%s()" % class_name
exec(str_exec)
if Reflector().create_object(module_class, Transformer):
    result =
module_class

............

很明显,这样写是多余的。。。。只是去判断了一下实例是否是另一个类的子类,有必要么有必要么,这样写还有必要添加那个类吗。。。

###########################################################################
我是在想一个问题,exec("from xxx.xxx import
XXX")的时候,这语句放到别的地方,在项目中直接引用能用吗?他能找到项目所在的包??
所以今天果断先在项目中实现代码
    instance = None

    import_str = "from %s
import %s" % (class_file_path.replace("/", "."), class_name)

    exec(import str)

    instance_str = "instance
= %s()" % class_name
    exec(instance_str)
    print
type(instance)
>>> instance
简单测试了一下,这样是可以实现的哦~
打印出来的类型也正是instance,是一个实例,而不是classobj。
什么是classobj呢?
简单来说,类的名字,就叫classobj。

###########################################
    @staticmethod

    def
create_instance(class_file_path, class_name, *args,
**kwargs):
     
  """
     
  创建实例, (from xxx import xxx) --> (from
class_file_path import class_name)
     
  :param class_file_path: py路径
crawler/dao/userDao
     
  :param class_name:类名称
     
  :param args: 参数列表
     
  :param kwargs: 参数列表
     
  :return:返回类实例,异常返回None
     
  """
     
  # instance_name =
class_file_path.split("/")[-1]
     
  instance = None
     
  imported = False
     
  import_str = "from %s import %s" %
(class_file_path.replace("/", "."), class_name)
     
  try:
     
      exec
(import_str)
     
      imported =
True
     
  except SyntaxError, e:
     
     
logging.error(u"创建实例:导入模块[%s]语法错误,e:%s。" % (import_str, e))
     
  except (ImportError, NameError), e:
     
      print
type(import_str)
     
     
logging.error(u"创建实例:导入模块[%s]不存在,e:%s。" % (import_str, e))
     
  if not imported:
     
      return
instance

     
  instance_str = "instance = %s(*args, **kwargs)"
% (class_name)
     
  try:
     
      exec
(instance_str)
     
  except SyntaxError, e:
     
     
logging.error(u"创建实例:类实例[%s]语法错误, e:%s。" % (instance_str, e))
     
  except NameError, e:
     
     
logging.error(u"创建实例:类实例[%s]不存在,e:%s。" % (instance_str, e))
     
  except TypeError, e:
     
     
logging.error(u"创建实例:类实例[%s]参数错误,e:%s。" % (instance_str, e))
     
  return instance

直接上代码吧,如上。。
用法也简单,  
test_instance = Reflector.create_instance(class_file,
class_Name)
if test_instance:
print dir(test_instance)
else:
    print "动态实例类出现异常"

####################################################

测试用例:

// myproject/test/test.py

class Test(object):

   
def init(self, name="hello world"):
 
  print "test create instance kwargs name:",
name

def hello(self):

    print "test create instance
call method." 

//
myproject/main.py
from
utils.reflection.reflector import Reflector

class_instance
= Reflector.create_instance("test/test", "Test", name="Zhipeng
Zhang")
class.hello()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: