连接类,静态还是实例?

1 投票
2 回答
1111 浏览
提问于 2025-04-17 04:34

我正在尝试写一个类,这个类的主要功能是:

  • 根据另一个类的属性和配置文件中的主机/端口信息,构建一个特定的URL
  • 建立连接
  • 解析响应

    class Foo(object):
        def __init__(self, a, b):
            self.a = a
            self.b = b
            self.connect_id = None
            self.response = None
    
        def something_that_requires_bar(self):
            # call bar
            pass
    
        # ...other methods
    

那么,这个连接类应该是一些静态方法或类方法,用来返回我想要的数据吗?

    class Bar(object):
        def build_url(self, Foo):
            # get host/port from config
            # build url based on Foo's properties
            return url

        def connect(self, url):
            # connects to the url that was built
            return Bar.parse_response(the_response)

        def parse_response(self, response):
            # parses response

还是说,我应该创建一个对象来保存我需要的数据,这样在连接之后我可以从中提取数据?

    class Bar(object):
        def __init__(self, foo):
            self.url = 

        def _build_url(self):
            # build url based on Foo's properties            
            self.url = # do something with Foo

        def _parse_response(self, response):
            # parses response

        def connect(self, url):
            # connects to the url that was built
            self.raw_response = urllib.urlopen(self.url).read()
            self.parsed_response = self._parse_response(self.raw_response)

或者甚至是两者结合的方式?

    class Bar(object):
        def __init__(self, foo):
            self.foo = foo
            self.url = self._build_url()

        def _build_url(self):
            # build url based on Foo's properties            
            self.url = # do something with Foo

        def _parse_response(self, response):
            # parses response

        @classmethod
        def connect(cls, Foo):
            # connects to the url that was built
            bar = Bar(Foo)
            self._build_url()
            self.raw_response = urllib.urlopen(self.url).read()
            self.parsed_response = self._parse_response(self.raw_response)
            return bar

2 个回答

0

嗯……为什么不把它分成两个类呢?一个类专门用来从配置中提取信息,另一个类则用来把这些信息和其他类的信息结合起来,完成你需要做的任务。根据这些任务的具体内容,可能还可以进一步细分。

另外,正如Wilduck提到的,从中提取信息的Foo接口也值得考虑……要确保“组合器”对Foo实例的了解不要超过必要的范围。

class Config( object ):
    '''
    read configuration from file
    '''

    configurations = {}
    def __new__( cls, config_file ):
        try:
            return cls.configurations[ config_file ]
        except KeyError:
            return super( Config, cls ).__new__( cls, config_file )

    def __init__( self, config_file ):
        if getattr( self, 'config_read', False ): 
            return
        self.read_config( config_file )
        self.config_read = True

    def read_config( self ):
        ...

class Combiner( object ):
    '''
    build url based on config and other object
    '''

    def __init__( self, config_file, foo ):
        self.config = Config( config_file )
        self.foo = foo

    def build_url( self ):
        ...

    def connect( self ):
        ...

    def parse_response( self ):
        ...
1

一个类最好能代表一组清晰且一致的行为。有时候,什么是最合适的并不总是很明确,但在你的情况下,我建议把每一个步骤都写成一个独立的类或函数,像这样:

def build_url(foo):
    # build the url from foo
    return the_url

def get_response(url):
    # do the connection, read the response
    return the_response

def parse_response(response):
    # parse the response
    return parsed_response

response = get_response(build_url(foo_object))
stuff_you_want = parse_response(response)

如果这些步骤需要更多的内部逻辑,使用类而不是函数也是可以的。比如,处理网址和解析响应的逻辑放在类里可能会更合适:

class Url(object):
    def __init__(self, foo):
        self._url = self._build_url_from_foo(foo)

    def _build_url_from_foo(self, foo):
        # do the url stuff
        return the_url

    def url_string(self):
       return self._url

class ResponseWrapper(object):
    def __init__(self, response):
        self._response = response

    def parse(self):
        # parsing logic here
        return parsed_response

response = ResponseWrapper(get_response(Url(foo)))
response.parse()

撰写回答