创建一组Python类

Con*_*ler 1 python class code-organization data-structures

我有一个代表请求的类.我有一组非常具体的请求,例如"I-95","P-22"等,它们执行不同的功能并由控制器类调用.这样做的最佳方法是什么,以便人们可以轻松地在路上添加更多请求?

我现在有这样的事情:

class Requests:
    def __init__(self):
            self.types = [
                    'I-95',
                    'P-22',
                    ...
            ]

    def generate_request(self,type, Data):
            # Here I would call the appropriate case for the type, e.g. P-22
Run Code Online (Sandbox Code Playgroud)

请求案例将在其自己的单独文件中,如下所示:

class P-22:
    # Members
    def __init__(self, Data):
        # Set data members
    def request(self):
        # Submit request
Run Code Online (Sandbox Code Playgroud)

我可以在控制器中创建一个请求

f = Requests()
f.generate_request('RC75')
Run Code Online (Sandbox Code Playgroud)

我正在努力寻找尽可能干净且易于扩展的东西.谢谢!

Elw*_*ens 8

尝试类似的东西:

class BaseRequest:
    name = None


class FooRequest(BaseRequest):
    name = 'I-95'

    def response(self):
        return "foo"


class BarRequest(BaseRequest):
    name = 'P-22'

    def response(self):
        return "bar"


class RequestManager:

    def __init__(self):
        self.requests = {
            FooRequest.name: FooRequest,
            BarRequest.name: BarRequest
        }

    def generate_request(self, name):
        if name in self.requests:
            return self.requests[name]()

    def register_request(self, request_class):
        assert issubclass(request_class, BaseRequest), \
            'Request class not a subclass of BaseRequest'
        assert hasattr('name', request_class) and isinstance(request_class.name, str), \
            'Request name not correctly configured'
        self.requests[request_class.name] = request_class
Run Code Online (Sandbox Code Playgroud)

然后:

manager = RequestManager()
request = manager.generate_request('I-95')
if request is not None:
    print(request.response()) # "foo"
Run Code Online (Sandbox Code Playgroud)

并且用于注册新请求:

class NewRequest(BaseRequest):
    name = 'N-1'

    def response(self):
        return "new"

manager = RequestManager()
manager.register_request(NewRequest)
request = manager.generate_request('N-1')
if request is not None:
    print(request.response()) # "new"
Run Code Online (Sandbox Code Playgroud)

我个人认为使用SingleManager模式为RequestManager 更好(未经测试!):

class RequestManager:

    instance = None

    class __RequestManager:
        requests = {
            FooRequest.name: FooRequest,
            BarRequest.name: BarRequest
        }

        def generate_request(self, name):
            if name in self.requests:
                return self.requests[name]()

        def register_request(self, request_class):
            assert issubclass(request_class, BaseRequest), \
                'Request class not a subclass of BaseRequest'
            assert hasattr('name', request_class) and isinstance(request_class.name, str), \
                'Request name not correctly configured'
            self.requests[request_class.name] = request_class

    def __new__(cls):
        if not cls.instance:
            cls.instance = cls.__RequestManager()
        return cls.instance

    @staticmethod
    def getInstance():
        return RequestManager()
Run Code Online (Sandbox Code Playgroud)

这将创建一个静态可访问的RequestManager实例:

manager = RequestManager.getInstance()
# Rest same as before, register some requests, etc.

manager2 = RequestManager.getInstance() # This is actually the same manager ie. the same instance!
Run Code Online (Sandbox Code Playgroud)

managermanager2共享相同的请求字典,因此通过其中一个更新适用于两者(技术上讲同一个经理,因为您检索两次相同的实例)