我很难理解何时使用实例方法而不是静态方法。另外,我不知道我的函数是否是静态的,因为没有@staticmethod装饰器。当我调用其中一个方法时,我能够访问类函数吗?
我正在开发一个将信息发送到数据库的webscraper。它设置为每周运行一次。我的代码结构如下所示
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
这是基本结构。代码是有用的但我不知道我是否正确使用方法(函数?)并且可能错过了将来使用我的代码的方法。我甚至可能编写错误的代码,这会导致错误,因为我没有遵循最佳实践,因此难以调试。
阅读有关何时使用类和实例方法的内容。我不明白为什么我会用它们。如果我想建立网址或从网站上提取数据,我会调用build_url或get_web_data函数。我不需要该函数的实例来跟踪任何单独的事物。我无法想象什么时候我需要保持一些独立的东西,我认为这是问题的一部分。
我认为我的问题与之前的问题不同的原因是:解释差异的概念性例子似乎在我坐下来编写代码时对我没有帮助。我没有遇到使用不同方法解决的现实世界问题,这些方法显示我何时应该使用实例方法,但在查看代码的概念示例时,实例方法似乎是必需的。
谢谢!
答案 0 :(得分:2)
此代码根本不需要是一个类。它应该只是一对功能。您无法理解为什么需要实例方法,因为您没有理由首先实例化该对象。
答案 1 :(得分:1)
从给定的示例中,毕竟不需要Get
类,因为您使用它就像一个额外的命名空间。你没有任何状态'您希望在类或类实例中保留。
看起来好事就是拥有单独的模块并在其中定义这些功能。这样,在导入此模块时,您可以拥有所需的此命名空间。
答案 2 :(得分:1)
类可用于表示对象,也可用于在公共名称空间下对函数进行分组。
当一个类代表一个对象时,就像猫一样,这个对象在逻辑上可以做的任何事情都应该是一个实例方法,比如喵喵叫。
但是当你有一组静态函数彼此相关或者通常一起用来实现一个共同的目标时,比如build_url
和web_data
,你可以让你的代码更清晰,通过将它们置于静态类下来进行组织,静态类提供了一个通用命名空间,就像你一样。
因此,在我看来,您选择的结构是合法的。但值得考虑的是,您可以在更明确的OOP语言(如Java)中找到更多静态类,而在python中,更常见的是使用模块进行名称空间分离。
答案 3 :(得分:1)
您在代码中编写的函数是实例方法,但它们编写错误。
实例方法必须将self
作为第一个参数
即def build_url(self, url_paramater1, url_parameter2, request_date):
然后你就这样称呼它
get_inst = Get()
get.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.build_url(url_paramater1, url_parameter2, request_date)
但您可能会问的当前代码有什么问题? 尝试从这样的实例调用它,你会看到问题
get_inst = Get()
get.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