python将巨型函数转换为Class
我一直在努力学习课程一段时间.是否有任何人可以帮助我理解使用类.任何帮助深表感谢.
当直接调用def scrapper时,下面的代码可以正常工作. Scrapper类是我对类的解释.我相信我现在想要调用实例,但我不确定究竟是怎么回事.该脚本不会产生任何错误,所以我很丢失.谢谢,我希望这是一个合适的问题. import requests import re from bs4 import BeautifulSoup as BS class Scrapper(): def __init__(self): self = self def requests(self): url_var = raw_input("Please input url: ") url = requests.get('%s' %url_var,auth=('','')) return BS(url.text) def file_(self): with open("Desktop/Scripts/%s.txt"%url_var,"w+") as links: return links.write(self) def parse(self): links = self .find_all('a') for tag in links: link = tag.get('href',None) if link != None: return link else: print "Error in parsing html" if __name__ == "__main__": Scrapper() ### def scrapper(): url_var = raw_input("Please input url: ") url = requests.get('%s' %url_var,auth=('user','pass')) with open('Desktop/Scripts/formgrab.txt',"w+") as links: soup = BS(url.text) links.write(soup.prettify().encode('utf8')) links = soup.find_all('a') for tag in links: link = tag.get('href',None) if link != None: print link ### 解决方法
你在这里提出了一个非常广泛的问题,这可能是技术上偏离网站的主题,但这让我很烦恼,以至于没有人可以向你解释一个对现代编程如此基础和关键的话题,我将回答你无论如何.这个禅的那一刻,你也试图长期躲避我,所以我理解.
理解类 这可能有点刺耳,但既然你正在试图理解课程,那你就错了.如果您仔细考虑找到类的位置,您可能已经明白了原因.类是面向对象编程的一部分.你看?围绕对象编程.所以我们不应该谈论类,我们应该谈论对象.我们稍后会去上课. 好的,所以…了解对象 你说elsewhere:
好吧,我很抱歉这些教程浪费了你的时间.在这种情况下,我当然不认为你是唯一一个. 这些教程试图封装的内容是OOP的一部分,它非常有用:对象很好地模拟了现实世界的数据.但这只是大局的一部分,所以让我们回来吧.在我们试图理解为什么对象有用之前,它们是什么?我的意思是,如果你阅读其中的一些教程,你会发现一个对象可以是任何东西的概念(意思是真的,它可以模拟任何东西),但是因为我们人类倾向于通过分解它们并将它们包围来理解它们.,这个定义很普遍,几乎毫无意义. 有一个0700在fellow Stack Overflow user,我认为它非常简洁(强调原文):
国家和行为.这就是制作对象的原因. (我真的建议你给帖子一个完整的阅读,但我离题了.) 有对象只是有对象 正如您在前面提到的教程中看到的那样,人们对OOP感到兴奋的部分原因是能够使用编程对象对现实世界进行建模.这可以追溯到状态和行为.但是,由于我们的程序中没有任何狗和猫,所以很难看到连接.但是一切都说OOP真的很好而且无处不在所以你应该使用它,对吗?这导致人们在不理解对象的情况下采用OOP的一部分,并导致错误的重构.这个问题的标题显示了这种想法:我有一个巨大的功能,但每个人都说我应该使用类,所以我应该把它变成一个类,对吧?错误.至少,不一定. 首先,应该注意的是,面向对象的编程虽然流行,但只有一个paradigm.在functional programming,一切都基于函数而不是对象,有一些非常有趣的效果. Python部分支持函数式编程,包含map和reduce之类的东西,并且存在许多类似于shellcript的Python程序,这些程序很简单imperative.我的观点是,一般来说,如果你只限于使用OOP,那么它会产生不良结果为了使用OOP,如果你用Python(一种多范式语言)来做这件事,你就会不必要地限制自己的语言权力. 那我什么时候应该使用物体?什么是类与实例? 您应该使用对象来帮助您更好地概念化问题和/或帮助您组织程序.对象不仅仅是代码重用!您可以轻松地仅使用函数重用代码.几十年来,这是重用代码的唯一方法.使用对象的真正原因是,当你习惯这样做时,它提供了一个自然的框架来解决程序员每天面临的艰难决策:这个函数应该在哪里生活?做这个或那个应该控制什么?当一切都被分解成对象时,这些问题的答案开始变得更加明显. 假设您正在编写一个程序,它会告诉您文件中最长的单词.忘记图书馆和时尚的单行.让我们这样做: longest_word = '' longest_word_len = 0 with open('some_file.txt') as f: for line in f: for word in line.split(): word_len = len(word) if word_len > longest_word_len: longest_word_len = word_len longest_word = word print('The longest word is',longest_word,'at',longest_word_len,'characters.') 嘿!这很漂亮,而且效果很好.如果我不想在任何时候运行它而不必更改文件名,那肯定会很好……如果我把它放在一个函数中,我可以在它的目录中抛出一个__init__.py并导入它! def longest_word_in_file(filename): """Print a message about the longest word in the given file""" longest_word = '' longest_word_len = 0 with open(filename) as f: for line in f: for word in line.split(): word_len = len(word) if word_len > longest_word_len: longest_word_len = word_len longest_word = word print('The longest word is','characters.') 在那里,只有两个简单的修改,我们有力地将这些代码重构为我们可以导入到其他地方的东西,以及可以为任何文件提供所需结果的东西,而不仅仅是我们最初硬编码的文件. (顺便说一句,这使它可以重复使用,不是吗?)我们还给它一个有用的名称,指出它的作用(提示:行为). 假设我们为这个功能感到骄傲,我们向所有朋友展示了我们制作的东西,并且有一位朋友评论说:“酷!它看到的最长的字是什么?”嗯,好问题.现在,我们的小功能只是完成它的工作,然后打包并称它为一天.它不会跟踪呼叫之间的任何内容.那是对的:它是无国籍的!你的朋友询问有关另一次重构的调用的统计数据:这次是一个对象. 考虑一下,现在我们有了先决条件:状态和行为.我们知道它的作用以及它需要跟上的步伐.但我们需要考虑的第三件事是:它是什么?当你编写一个函数时,你只想到它的作用.现在我们需要知道它是什么.由于它找到文件中最长的单词,我会说它是一个LongestWordFinder.有创意,我知道. class LongestWordFinder(): """ Find the longest word in a file and track statistics on words found. """ longest_word = '' longest_word_len = 0 longest_word_ever = '' longest_word_ever_len = 0 def find_in_file(self,filename): self.longest_word = '' self.longest_word_len = 0 with open(filename) as f: for line in f: for word in line.split(): word_len = len(word) if word_len > self.longest_word_len: self.longest_word_len = word_len self.longest_word = word if word_len > self.longest_word_ever_len: self.longest_word_ever_len = word_len self.longest_word_ever = word print('The longest word is',self.longest_word,self.longest_word_len,'characters.') print('The longest word I have ever seen is',self.longest_word_ever,self.longest_word_ever_len,'characters.') 哇……变了很多.好吧,不是真的.我们的功能现在存在于一个类中,并且具有不同的名称.此外,我们现在正在跟踪两件事:既是当前文件中最长的单词,也是有史以来最长的单词.唯一真正改变的是在一些地方使用self来访问变量,这些变量现在属于类而不仅仅是函数的本地变量.这就是状态在呼叫之间持续存在的方式! 所以这是一个有趣的问题,问你自己是否还在读这个:有多久了?你知道吗,就像我们见过的最长的一句话一样?这也将告诉我们另一个问题的答案:我们究竟如何使用这个东西?如果将该类复制到lwf.py中,则在该目录中打开Python解释器: >>> from lwf import LongestWordFinder >>> lwf = LongestWordFinder() >>> lwf.find_in_file('test.txt') The longest word is watermelon at 10 characters. The longest word I have ever seen is watermelon at 10 characters. >>> lwf.find_in_file('test2.txt') The longest word is freakshow at 9 characters. The longest word I have ever seen is watermelon at 10 characters. 为了使用我们的类,我们必须实例化它.也就是说,我们创建了它的一个实例.因此,它所见过的最长的单词,意味着实例在其生命周期中看到的最长的单词.由于实例绑定到变量,这实际上是变量的范围.当我关闭Python解释器时,我复制了该代码,实例已经消失 – 它的生命周期结束了 – 它跟上的所有状态都消失了.另外,如果我们创建另一个实例: >>> lwf2 = LongestWordFinder() >>> lwf2.find_in_file('test.txt') The longest word is freakshow at 9 characters. The longest word I have ever seen is freakshow at 9 characters. 它有不同的回忆.它从未见过test.txt,因此它不了解西瓜. >>> lwf.find_in_file('test2.txt') The longest word is freakshow at 9 characters. The longest word I have ever seen is watermelon at 10 characters. 不过,第一个仍然存在. 持久的国家 如果我们想要在关闭Python解释器后记住状态怎么办?好吧,如果我们想要真的很花哨,我们可以使用数据库,但我们只是简单地做事.我们把它写在一个文件中.当我们在它的时候,让我们重构我们的类,以便我们可以传递它的文件. class LongestWordFinder(): """ Find the longest word in a file and track statistics on words found. """ def __init__(self,memory_file=None): self.longest_word = '' self.longest_word_len = 0 if memory_file is not None: with open(memory_file) as memory: word,word_len = memory.read().strip().split(':') self.longest_word_ever = word self.longest_word_ever_len = word_len else: self.longest_word_ever = '' self.longest_word_ever_len = 0 def find_in_file(self,'characters.') def save(self,memory_file): with open(memory_file,'w') as memory: memory.write('%s:%s' % (self.longest_word_ever,self.longest_word_ever_len)) 这里发生了两件事.一,我们有一个新方法save,它在一个文件中写入,因此它可以记住它所见过的最长的单词.二,我们现在有一个__init__方法为我们设置状态,包括如果我们给它一个那么从该文件中读取.你可能已经注意到__something__意味着它是一个“魔术”的东西,它允许我们覆盖它.在__init __的情况下,它是在您创建实例时设置实例的函数.现在,假设我们已经运行了一两次,称为save,然后退出我们的解释器,当我们重新启动时,我们可以这样做: >>> lwf = LongestWordFinder('memory.txt') >>> lwf.longest_word_ever 'watermelon' 我们回到了我们开始的地方. 太多了……我会总结一下. 正如您所看到的,有充分的理由想要将函数重构为类.还有一些不好的.您可能还注意到,有可能解释对象的好处,而从未提及过狗,猫,构造函数,封装甚至继承!*对象很棒,因为它们为您提供了一种跟踪状态的方法,同时提供了直观的方式来为您的程序建模,并轻松地让您传递已经工作的代码,而不会使用一英里长的参数列表的函数.希望这可以帮助你grok为什么对象是有用的,以及何时以及为什么你可能想要将“巨型功能”变成一个.快乐的编码. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |