2009-09-17 3 views
24
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.all().) Является именем класса, которое определяет таблицы данных в Google BigTable с помощью Python.Python: Передача имени класса в качестве параметра функции?

Я хочу сделать что-то вроде этого:

 TestRetrievalOfClass(Subscriber) 
or  TestRetrievalOfClass("Subscriber") 

Спасибо, Нил Walters

ответ

17
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) 
+0

Круто, я не знаю, что вы могли бы передать класс так же, как и любой другой переменной. Мне не хватало этой связи. – NealWalters

+7

функции, методы, класс, модули. Все это объект первого класса в python, который вы можете обойти. – 2009-09-17 05:31:27

10

Если передать объект класса непосредственно, как в коде между «как это» и " или ", , вы можете получить его имя как атрибут __name__.

Начиная с именем (как в коде после «или») делает его очень трудно (и не однозначна), чтобы получить объект класса, если у вас есть некоторое представление о том, где объект класса может содержаться - так почему бы не передать объект класса?

+1

+1: Классы - это объекты первого класса - вы можете назначить их переменным и параметрам и всем остальным. Это не C++. –

+0

OBJ = globals() [className]() где className - это переменная, содержащая строку имени класса. Получил это от старого сообщения здесь: http://www.python-forum.org/pythonforum/viewtopic.php?f=3&t=13106 – NealWalters

+1

@NealWalters, который не будет работать, если класс определен где угодно ELSE, чем в начале -уровень в текущем модуле (в функции, в другом классе, в другом модуле и т. д.), поэтому в целом неплохая идея. –

1

Небольшое изменение кода Неда, который я использовал. Это веб-приложение, , поэтому я запускаю его, запустив процедуру get через 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