加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python将巨型函数转换为Class

发布时间:2020-12-20 12:41:03 所属栏目:Python 来源:网络整理
导读:我一直在努力学习课程一段时间.是否有任何人可以帮助我理解使用类.任何帮助深表感谢. 当直接调用def scrapper时,下面的代码可以正常工作. Scrapper类是我对类的解释.我相信我现在想要调用实例,但我不确定究竟是怎么回事.该脚本不会产生任何错误,所以我很丢失
我一直在努力学习课程一段时间.是否有任何人可以帮助我理解使用类.任何帮助深表感谢.

当直接调用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
###

解决方法

你在这里提出了一个非常广泛的问题,这可能是技术上偏离网站的主题,但这让我很烦恼,以至于没有人可以向你解释一个对现代编程如此基础和关键的话题,我将回答你无论如何.这个禅的那一刻,你也试图长期躲避我,所以我理解.

Warning: Long-Winded Tutorial Ahead. Not for the faint of heart.

理解类

这可能有点刺耳,但既然你正在试图理解课程,那你就错了.如果您仔细考虑找到类的位置,您可能已经明白了原因.类是面向对象编程的一部分.你看?围绕对象编程.所以我们不应该谈论类,我们应该谈论对象.我们稍后会去上课.

好的,所以…了解对象

你说elsewhere:

I’ve read several tutorials… I understand that classes are used for storing data and to layout a blueprint,I’ve just never had a reason to use them so it’s never sunk in. I’ve read a lot of tutorials that said how to create ‘class dog’,‘class cat’,‘dog.name = “scruff”‘,but for the life of me I can’t see how it applies to my situation. Thanks anyway guys,sorry for wasting your time.

好吧,我很抱歉这些教程浪费了你的时间.在这种情况下,我当然不认为你是唯一一个.

这些教程试图封装的内容是OOP的一部分,它非常有用:对象很好地模拟了现实世界的数据.但这只是大局的一部分,所以让我们回来吧.在我们试图理解为什么对象有用之前,它们是什么?我的意思是,如果你阅读其中的一些教程,你会发现一个对象可以是任何东西的概念(意思是真的,它可以模拟任何东西),但是因为我们人类倾向于通过分解它们并将它们包围来理解它们.,这个定义很普遍,几乎毫无意义.

有一个0700在fellow Stack Overflow user,我认为它非常简洁(强调原文):

Object-oriented programming is about objects: bundles of state and behavior. The rest is optional fluff.

国家和行为.这就是制作对象的原因. (我真的建议你给帖子一个完整的阅读,但我离题了.)

有对象只是有对象

正如您在前面提到的教程中看到的那样,人们对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为什么对象是有用的,以及何时以及为什么你可能想要将“巨型功能”变成一个.快乐的编码.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读