操作来自namedtuple()派生类的属性

时间:2015-06-04 03:01:59

标签: python inheritance namedtuple attr-protected

我有一个名为EasyUrl()的类,它来自urlparse.Parseresult()。在调用ParseResult()时实例化了urlparse.urlparse(url),我在EasyUrl()内部有一个静态方法,它将实例化的ParseResult()对象的类类型更改为EasyUrl()对象。我将urlparse.urlparse()函数和类类型转换包装到函数parse_url()中。

这样一个功能背后的原因,是我试图解决一个单独的问题,我不需要答案,但想要一个,我在TypeError期间调用__new__时得到EasyUrl()实例化过程,它让我知道我的参数数量无效。

直接实例化# snippet url = 'stackoverflow.com' url = EasyUrl(url) # snippet end Output: TypeError: __new__() takes exactly 7 arguments (2 given) 时收到错误

ParseResult()

namedtuple()类继承自class ParseResult(namedtuple('ParseResult', 'scheme netloc path params query fragment'), ResultMixin): __slots__ = () def geturl(self): return urlunparse(self)

摘自urlparse库

ParseResult()

现在我已经描述了代码的一些功能,这就是问题所在。我无法访问命名的元组(ParseResult)属性。我正试图为import urlparse def parse_url(url): """ Return a parsed EasyUrl() object""" parse_result = urlparse.urlparse(url) return EasyUrl.EvolveParseResult(parse_result) class EasyUrl(urlparse.ParseResult): @staticmethod def EvolveParseResult(parse_result): """ Change the type of class into a EasyUrl() Object.""" parse_result.__class__ = EasyUrl easy_url = parse_result # For readabilty easy_url.init() return easy_url def __init__(self, url): self = parse_url(url) # doesn't work def init(self): self.url = self.geturl() #self.set_scheme_if_non() # Uncomment when no error is raised def set_scheme_if_non(self, scheme='http'): if not self.scheme: self.scheme = scheme self.url = self.geturl() # Rebuild our url with the new scheme # Passes the set_scheme_if_non trigger #url = 'https://stackoverflow.com' # Fails if statment, then attempts to set the variable, # but error is raised: AttributeError: can't set attribute url = 'stackoverflow.com' # Will give the error: TypeError: __new__() takes exactly 7 arguments (2 given) #url = EasyUrl(url) # works fine, I don't know why. Except that I can't access # the tuples attributes in the class definition url = parse_url(url) print url.scheme # Works fine url.set_scheme_if_non() # Raises an error 实现默认方案,如果它丢失了。

但我无法访问类定义中的属性。

File "/home/crispycret/easyurl.py", line 50, in <module>
  url.set_scheme_if_non() # Raises an error
File "/home/crispycret/easyurl.py", line 29, in set_scheme_if_non
  self.scheme = scheme

AttributeError: can't set attribute

输出

{{1}}

1 个答案:

答案 0 :(得分:1)

为什么不从头开始创建一个新类并从ParseResult转移所有属性?

import urlparse

class EasyURL(object):
    def __init__(self, parse_result):
        self.scheme = parse_result.scheme
        self.netloc = parse_result.netloc
        self.path = parse_result.path
        self.params = parse_result.params
        self.query = parse_result.query
        self.fragment = parse_result.fragment

    @classmethod
    def from_url(cls, url):
        return cls(urlparse.urlparse(url))

if __name__ == '__main__':
    url = 'http://foo.bar.com:8888/path/to/script.php?a=1&b=2'

    # Call from_url class method, which is very convenient
    easy_url = EasyURL.from_url(url)

    # Or, do it yourself
    easy_url = EasyURL(urlparse.urlparse(url))

您现在可以根据需要向此类添加任何其他方法。

更新

  • namedtuple是一个动态创建新类型的函数。顺便说一下,除非我们为EasyURL
  • 添加一些代码,否则我们的__getitem__()对象不会充当元组。
  • ParseResult不允许您更改scheme等属性,因此没有理由继承它。