Python:将类名作为参数传递给函数?

33
class TestSpeedRetrieval(webapp.RequestHandler):
  """
  Test retrieval times of various important records in the BigTable database 
  """
  def get(self):
      commandValidated = True 
      beginTime = time()
      itemList = Subscriber.all().fetch(1000) 

      for item in itemList: 
          pass 
      endTime = time()
      self.response.out.write("<br/>Subscribers count=" + str(len(itemList)) + 
           " Duration=" + duration(beginTime,endTime)) 
我如何将上述内容转化为一个函数,其中我需要传递类的名称? 在上面的例子中,`Subscriber`(在`Subscriber.all().fetch`语句中)是一个类名,它用于使用Python定义Google BigTable中的数据表。
我想要做这样的事情:
       TestRetrievalOfClass(Subscriber)  
or     TestRetrievalOfClass("Subscriber")  

谢谢,Neal Walters

3个回答

30
class TestSpeedRetrieval(webapp.RequestHandler):
  """
  Test retrieval times of various important records in the BigTable database 
  """
  def __init__(self, cls):
      self.cls = cls

  def get(self):
      commandValidated = True 
      beginTime = time()
      itemList = self.cls.all().fetch(1000) 

      for item in itemList: 
          pass 
      endTime = time()
      self.response.out.write("<br/>%s count=%d Duration=%s" % (self.cls.__name__, len(itemList), duration(beginTime,endTime))

TestRetrievalOfClass(Subscriber)  

酷,我不知道你可以像任何其他变量一样传递一个类。我缺少了那个连接。 - NealWalters
10
函数、方法、类、模块在 Python 中都是一等对象,可以进行传递。 - undefined

12
如果你直接传递类对象,就像在你的代码中在“like this”和“or”之间,你可以通过__name__属性获取它的名称。
从名称开始(就像在你的代码中在“or”之后)会使得检索类对象变得非常困难(并且不明确),除非你有一些关于类对象可能被包含在哪里的指示 - 那么为什么不直接传递类对象呢?!

3
+1:类是一等对象——您可以将它们分配给变量和参数以及其他所有内容。这与C++不同。 - S.Lott
OBJ = globals()className其中,className是包含类名称字符串的变量。这段代码来自于此处的旧帖子:http://www.python-forum.org/pythonforum/viewtopic.php?f=3&t=13106 - NealWalters
2
@NealWalters,如果类在当前模块中的顶层以外的任何地方定义(在函数中、在另一个类中、在另一个模块中等等),那么这种方法就行不通了,因此一般来说并不是一个好主意。 - Alex Martelli
@Ned Batchelder,@Alex Martelli,对于一个类名参数,最合适的类型注释(Python 3.6+)是什么?@Mikhail Gerasimov说我可以使用Callable,但这听起来有误导性。 - y2k-shubham

3

以下是我使用的 Ned 代码的略微变化。这是一个网络应用程序,因此我通过 URL 运行获取例程来启动它:http://localhost:8080/TestSpeedRetrieval。我没有看到需要 init

class TestSpeedRetrieval(webapp.RequestHandler):
  """
  Test retrieval times of various important records in the BigTable database 
  """
  def speedTestForRecordType(self, recordTypeClassname):
      beginTime = time()
      itemList = recordTypeClassname.all().fetch(1000) 
      for item in itemList: 
          pass # just because we almost always loop through the records to put them somewhere 
      endTime = time() 
      self.response.out.write("<br/>%s count=%d Duration=%s" % 
         (recordTypeClassname.__name__, len(itemList), duration(beginTime,endTime)))

  def get(self):

      self.speedTestForRecordType(Subscriber) 
      self.speedTestForRecordType(_AppEngineUtilities_SessionData) 
      self.speedTestForRecordType(CustomLog) 

输出:

Subscriber count=11 Duration=0:2
_AppEngineUtilities_SessionData count=14 Duration=0:1  
CustomLog count=5 Duration=0:2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接