连接类,静态还是实例?

时间:2011-10-18 18:20:48

标签: python oop class static-methods

我正在尝试编写一个封装逻辑的类:

  • 根据配置文件中的其他类的属性和主机/端口信息构建特定的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
    

连接类是否应该是一堆返回我正在寻找的数据的staticmethods / classmethod?

    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 :(得分: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)

如果这些步骤中的任何一个步骤需要更多的内部逻辑,那么您可以使用类'而不是函数执行相同的操作。例如url和响应解析逻辑可能在类中有意义:

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()

答案 1 :(得分:0)

嗯......好吧,为什么不把它分成两类;一个用于从配置中提取信息,另一个用于将该信息与来自类的信息组合以执行您需要执行的任务。根据进入这些任务的内容,进一步分解可能是有意义的。

另外,正如Wilduck所说,检索信息的Foo接口需要考虑......确保“Combiner”不需要了解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 ):
        ...