Python 何时使用实例方法与静态方法

Python when to use instance vs static methods

我很难理解何时使用实例方法与静态方法有意义。另外,我不知道我的函数是否是静态的,因为没有 @staticmethod 装饰器。当我调用其中一种方法时,我能否访问 class 函数?

我正在开发一个将信息发送到数据库的网络爬虫。它设置为 运行 每周一次。我的代码结构如下所示

import libraries...
class Get:
    def build_url(url_paramater1, url_parameter2, request_date):
        return url_with_parameters

    def web_data(request_date, url_parameter1, url_parameter2): #no use of self
        # using parameters pull the variables to look up in the database
        for a in db_info:
            url = build_url(a, url_parameter2, request_date)
            x = requests.Session().get(url, proxies).json()
            #save data to the database
        return None

    #same type of function for pulling the web data from the database and parsing it

if __name__ == ‘__main__’:
    Get.web_data(request_date, url_parameter1, url_parameter2)
    Parse.web_data(get_date, parameter) #to illustrate the second part of the scrapper

这是基本结构。该代码可以正常运行,但我不知道我是否正确使用了这些方法(函数?),并且可能会错过将来使用我的代码的方法。我什至可能会编写糟糕的代码,这些代码会导致错误难以调试,这仅仅是因为我没有遵循最佳实践。

阅读有关何时使用 class 和实例方法的内容后。我不明白为什么要使用它们。如果我想要构建 url 或从网站提取数据,我会调用 build_url 或 get_web_data 函数。我不需要函数的实例来跟踪任何单独的东西。我无法想象什么时候我需要将某些东西分开,我认为这是问题的一部分。

我认为我的问题与之前的问题不同的原因是:当我坐下来编写代码时,解释差异的概念示例似乎对我没有帮助。我还没有 运行 了解用不同方法解决的现实世界问题,这些问题表明我什么时候应该使用实例方法,但在查看概念性代码示例时,实例方法似乎是强制性的。

谢谢!

此代码根本不需要 class。它应该只是一对函数。您不明白为什么需要实例方法,因为您一开始就没有理由实例化对象。

从给定的示例来看,毕竟不需要 Get class,因为您使用它就像使用附加名称空间一样。在 class 或 class 实例中,您没有任何要保留的 'state'。

拥有单独的模块并在其中定义这些功能似乎是件好事。这样,在导入此模块时,您就可以拥有所需的命名空间。

类可以用来表示对象,也可以将函数分组在一个共同的命名空间下。

当一个class代表一个对象,比如一只猫,任何这个对象'can do',逻辑上,都应该是一个实例方法,比如meowing。

但是当你有一组彼此相关或通常一起使用以实现共同目标的静态函数时,如 build_urlweb_data,你可以使你的代码通过将它们放在一个静态 class 下更清晰、更有条理,它提供了一个通用的命名空间,就像您所做的那样。

因此我认为您选择的结构是合法的。不过,值得考虑的是,在更明确的 OOP 语言中,您会发现更多静态 classes,例如 Java,而在 python 中,使用模块进行名称空间分离更为常见。

你在代码中写的函数是实例方法,但是写错了。 实例方法必须self作为第一个参数

def build_url(self, url_paramater1, url_parameter2, request_date):

然后你就这样称呼它

get_inst = Get()
get_inst.build_url(url_paramater1, url_parameter2, request_date)

self 参数由 python 提供,它允许您访问 Get class 的所有属性和函数(无论是否静态)。

如果您不需要访问 class 中的其他函数或属性,那么您可以添加 @staticmethod 装饰器并删除 self 参数

@staticmethod
def build_url(url_paramater1, url_parameter2, request_date):

然后就可以直接调用了

Get.build_url(url_paramater1, url_parameter2, request_date)

或从 class 实例调用

get_inst = Get()
get_inst.build_url(url_paramater1, url_parameter2, request_date)

但是您可能会问您当前的代码有什么问题? 尝试从这样的实例调用它,您会看到问题

get_inst = Get()
get_inst.build_url(url_paramater1, url_parameter2, request_date)

创建实例有用的示例: 假设您想制作一个聊天客户端。

你可以这样写代码

class Chat:
    def send(server_url, message):
        connection = connect(server_url)
        connection.write(message)
        connection.close()

    def read(server_url):
        connection = connect(server_url)
        message = connection.read()
        connection.close()
        return message

但更简洁、更好的方法:

class Chat:

    def __init__(server_url):
        # Initialize connection only once when instance is created
        self.connection = connect(server_url)

    def __del__()
        # Close connection only once when instance is deleted
        self.connection.close()

    def send(self, message):
        self.connection.write(message)

    def read(self):
        return self.connection.read()

要使用最后一个 class 你可以

# Create new instance and pass server_url as argument
chat = Chat("http://example.com/chat")
chat.send("Hello")
chat.read()
# deleting chat causes __del__ function to be called and connection be closed
delete chat