【问题标题】:Exception when running a Python method from another class从另一个类运行 Python 方法时出现异常
【发布时间】:2011-04-29 03:57:50
【问题描述】:

这是我的代码。

import urllib2
import urllib
import json
from BeautifulSoup import BeautifulSoup

class parser:
    """
    This class uses the Beautiful Soup library to scrape the information from
    the HTML source code from Google Translate.

    It also offers a way to consume the AJAX result of the translation, however
    encoding on Windows won't work well right now so it's recommended to use
    the scraping method.
    """

    def fromHtml(self, text, languageFrom, languageTo):
        """
        Returns translated text that is scraped from Google Translate's HTML
        source code.
        """
        langCode={
            "arabic":"ar", "bulgarian":"bg", "chinese":"zh-CN",
            "croatian":"hr", "czech":"cs", "danish":"da", "dutch":"nl",
            "english":"en", "finnish":"fi", "french":"fr", "german":"de",
            "greek":"el", "hindi":"hi", "italian":"it", "japanese":"ja",
            "korean":"ko", "norwegian":"no", "polish":"pl", "portugese":"pt",
            "romanian":"ro", "russian":"ru", "spanish":"es", "swedish":"sv" }

        urllib.FancyURLopener.version = "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008070400 SUSE/3.0.1-0.1 Firefox/3.0.1"

        try:
            postParameters = urllib.urlencode({"langpair":"%s|%s" %(langCode[languageFrom.lower()],langCode[languageTo.lower()]), "text":text,"ie":"UTF8", "oe":"UTF8"})
        except KeyError, error:
            print "Currently we do not support %s" %(error.args[0])
            return

        page = urllib.urlopen("http://translate.google.com/translate_t", postParameters)
        content = page.read()
        page.close()

        htmlSource = BeautifulSoup(content)
        translation = htmlSource.find('span', title=text )
        return translation.renderContents()


    def fromAjaxService(self, text, languageFrom, languageTo):
        """
        Returns a simple string translating the text from "languageFrom" to
        "LanguageTo" using Google Translate AJAX Service.
        """
        LANG={
            "arabic":"ar", "bulgarian":"bg", "chinese":"zh-CN",
            "croatian":"hr", "czech":"cs", "danish":"da", "dutch":"nl",
            "english":"en", "finnish":"fi", "french":"fr", "german":"de",
            "greek":"el", "hindi":"hi", "italian":"it", "japanese":"ja",
            "korean":"ko", "norwegian":"no", "polish":"pl", "portugese":"pt",
            "romanian":"ro", "russian":"ru", "spanish":"es", "swedish":"sv" }

        base_url='http://ajax.googleapis.com/ajax/services/language/translate?'
        langpair='%s|%s'%(LANG.get(languageFrom.lower(),languageFrom),
                          LANG.get(languageTo.lower(),languageTo))
        params=urllib.urlencode( (('v',1.0),
                           ('q',text.encode('utf-8')),
                           ('langpair',langpair),) )
        url=base_url+params
        content=urllib2.urlopen(url).read()
        try: trans_dict=json.loads(content)
        except AttributeError:
            try: trans_dict=json.load(content)
            except AttributeError: trans_dict=json.read(content)
        return trans_dict['responseData']['translatedText']

现在在另一个名为 TestingGrounds.py 的类中,我想尝试这两种方法,但出现以下错误:

from Parser import parser

print parser.fromHtml("Hello my lady!", "English", "Italian")

Traceback(最近一次调用最后):文件“C:\Users\Sergio.Tapia\Documents\NetBeansProjects\BabylonPython\src\TestingGrounds.py”,第 3 行,在 print parser.fromHtml("Hello my Lady!", "English", "Italian") TypeError: unbound method fromHtml() must be called with parser instance as first argument (get str instance)

【问题讨论】:

  • 如果你只使用静态方法,你可能想要创建一个模块而不是一个类。 docs.python.org/tutorial/modules.html
  • parser.fromHtml() 不是静态方法。它是实例上的一个方法。

标签: python class methods module


【解决方案1】:

如果你想使用 fromHtml() 作为静态方法,如果你真的不需要在解析器中访问任何数据成员,你需要这样做(为了简洁起见)

class parser:
    @staticmethod
    def fromHtml(text, languageFrom, languageTo):
         # etc.

或者,如果您希望它既是静态方法又能够成为实例方法...

class parser:
    @classmethod
    def fromHtml(self, text, languageFrom, languageTo):
         # etc.

您现在可以将其用作parser.fromHtml()parser().fromHtml()

查看您的代码,我应该认为您只需要一个静态方法。

【讨论】:

    【解决方案2】:

    您必须拥有parser 类的实例,而不是调用该类本身的方法。

    from Parser import parser
    
    print parser().fromHTML("Hello my lady!", "English", "Italian")
    

    from Parser import parser
    
    p = parser()
    p.fromHTML(...)
    

    或者,您可以将 fromHTML 设为静态方法:

    class parser(object):   # you should probably use new-style classes
        ...
        @staticmethod
        def fromHTML(...):
            ...
    

    然后你可以像这样使用它:

    from Parser import parser
    
    print parser.fromHTML(...)
    

    【讨论】:

    • 最推荐的方法是什么?新建一个类的变量对象然后调用你需要的方法?我是 Python 新手,但熟悉 C#。在 C# 中,我会创建一个变量来保存解析器类,然后使用这些方法。谢谢!
    • 编辑后:啊太棒了!我不知道 python 可以在一行中间实例化这样的对象。太好了。
    • 这真的取决于你的用例。 parser 类是否需要单独的实例,每个实例都有不同的数据集?如果是这样,那么您可能希望将 fromHTML 保留为实例方法。如果你决定让它成为一个静态方法,不要给它一个self 参数,就像@Xorlev 显示的那样。无论哪种方式,Python 的语法都使得这两种方式都不会比另一种更冗长或更少(至少在这种情况下)。如果是实例方法,调用parser().fromHTML(),如果是静态方法,调用parser.fromHTML()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-24
    • 2021-08-06
    • 2015-06-29
    • 1970-01-01
    • 2022-09-27
    • 1970-01-01
    相关资源
    最近更新 更多