连接类、静态还是实例?

发布于 2024-12-10 11:55:14 字数 2089 浏览 1 评论 0原文

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

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

    类 Foo(对象):
        def __init__(自身, a, b):
            self.a = a
            self.b = b
            self.connect_id = 无
            自我响应=无
    
        def some_that_requires_bar(self):
            # 呼叫栏
            经过
    
        # ...其他方法
    

连接类应该是一堆返回我正在查找的数据的静态方法/类方法吗?

    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

I am trying to write a class that encapsulates the logic to:

  • build a specific url based on another class's properties and host/port information from a config file
  • make a connection
  • parses the response

    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
    

Should the connection class be a bunch of staticmethods/classmethods that return the data I'm looking for?

    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

or

Should I build an object that holds the data that I need so that I can extract the data from it after the connection?

    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)

or even a hybrid?

    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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

看海 2024-12-17 11:55:14

理想情况下,单个类应该代表一组清晰且有凝聚力的行为。有时并不总是清楚什么是最合适的,但在你的情况下,我会将你的每个步骤编码为一个不同的类或函数,如下所示:

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

A single class should ideally represent a clear and cohesive set of behaviour. Sometimes it isn't always clear what the best fit is, but in your case, I would code each of your steps as a distinct class or function something like this:

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)

You can do the same thing with class' instead of functions if any of those steps require more internal logic that would be better served in a class construct. e.g. it might make sense for the url and response parsing logic to be in classes:

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()
沙沙粒小 2024-12-17 11:55:14

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

另外,正如 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 ):
        ...

Hmm... well why not break it down into two classes; one for extracting info from config, and the other for combining that info with info from class to do the tasks you need to do. Depending on what goes into these tasks it might make sense to break things down even further.

Also, as Wilduck notes, the interface of Foo from which the info is retrieved bears thinking about... make sure that the "Combiner" doesn't need to know more than is healthy about Foo instances.

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 ):
        ...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文