1

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

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

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

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

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

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

谢谢!

4

4 回答 4

2

这段代码根本不需要是一个类。它应该只是一对功能。您看不到为什么需要实例方法,因为您没有理由首先实例化对象。

于 2018-02-10T12:59:00.613 回答
2

类可用于表示对象,也可用于在公共命名空间下对函数进行分组。

当一个类代表一个对象时,比如一只猫,这个对象“可以做”的任何事情,从逻辑上讲,都应该是一个实例方法,比如喵喵叫。

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

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

于 2018-02-10T13:04:38.213 回答
1

从给定的示例中,毕竟不需要Get类,因为您使用它就像一个附加的命名空间。在类或类实例中,您没有要保留的任何“状态”。

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

于 2018-02-10T13:03:18.083 回答
1

您在代码中编写的函数是实例方法,但它们编写不正确。实例方法必须作为self第一个参数

IEdef 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类的所有属性和函数——无论是静态的还是非静态的。

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

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

然后就可以直接调用了

Get.build_url(url_paramater1, url_parameter2, request_date)

或从类实例调用

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

要使用你做的最后一堂课

# 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
于 2018-02-10T13:27:11.100 回答