2016-10-19 2 views
0

Вот сценарий:Динамическое создание класса - Python

У меня есть два класса:

class A: 
    pass: 

class B: 
    pass 

Теперь я хочу, чтобы создать клиента, в том, что мне нужно иметь небольшой служебный метод, который должен верните шаблон/объект класса, например: class A, класс B, поскольку я передаю имя класса этой утилите, например get_obj(classA).

Теперь, это возможно? Если тогда, пожалуйста, предложите подход, так как я не получаю никакого правильного ответа на данный момент в Интернете.

Надеюсь, что у меня есть смысл.

+0

сделать классы [объектом] (https://jeffknupp.com/blog/2014/06/18/improve-your-python-python-classes-and-object-oriented-programming/) –

+1

Да, вы может просто иметь 'dict' like' cls = {'classA': A, 'classB': B} ', а затем вы можете вызвать' cls.get ('classA') 'для вашей реализации' get_obj'. Это старт, хотя, но без каких-либо подробностей о том, что вы есть _actually_, хотите сделать фактический ответ, может быть совсем другим. – metatoaster

+1

Зачем вам это нужно? Что такое пустой класс, к которому этот метод вернется, полезно? – Messa

ответ

2

Вот возможная реализация. Весь код содержится в одном «.py» файла

class A:                        
    pass                        


class B:                        
    pass                        

# map class name to class                          
_classes = {                       
     A.__name__: A,                    
     B.__name__: B,                    
}                         

def get_obj(cname):                      
    return _classes[cname]()                    

# test the function                          
if __name__ == '__main__':                   
    print get_obj('A') 

Он будет производить следующий вывод

<__main__.A instance at 0x1026ea950> 
0

Стандартная функция библиотеки namedtuple создает и возвращает класс. Внутри он использует exec. Это может быть вдохновение для того, что вам нужно.

код Источник: https://github.com/python/cpython/blob/master/Lib/collections/init.py#L356

+0

Забавно, что люди отрицают этот ответ, учитывая, что у дизайнеров самого языка, по-видимому, нет проблем с использованием 'exec' для такого рода вещей. –

+0

@RickTeachey Я ниспроверг его, потому что вопрос не о ** определении ** класса. О методе утилиты _small, который должен возвращать мой класс/объект класса, например: class A, класс B, когда я передаю имя класса этой утилите_. –

+0

Думаю, нам нужно больше разъяснений от первоначального спрашивающего, что он должен делать на самом деле. Хочет ли он просто искать диктофон, как в ответе @ AnthonyKong, или что-то более динамичное. – Messa

0

globals() возвращает словарь, содержащий все символы, определенные в глобальной области видимости модуля (включая классы A и B):

a_and_b_module.py

class A: pass 
class B: pass 

def get_cls(cls_name): 
    return globals()[cls_name] 

Если вы ищете для простоты

Если код, который будет вызывать эту функцию внутри модуля, то вы можете исключить функцию вообще и использовать globals()[cls_name] непосредственно.

Если код, который будет вызывать эту функцию вне модуля, то вы можете использовать функцию getattr:

a_and_b_module.py

class A: pass 
class B: pass 

another_file.py

import a_and_b_module 

cls_name = 'A' 
chosen_cls = getattr(a_and_b_module, cls_name) 

Если вы ищете для полного контроля

Проблема с выше подхода заключается в том, что он может вернуть что-либо определенное в a_and_b_module.py, не ограничивая себя A и B. Если вы хотите, чтобы убедиться, что только А и В могут быть возвращены:

class A: pass 
class B: pass 

allowed_classes = ('A', 'B') 

def get_cls(cls_name): 
    assert cls_name in allowed_classes 
    return globals()[cls_name] 

Примечание: вы также можете быть заинтересованы в концепции factory.