从派生的 namedtuple() 操作属性 class
Manipulating attributes from a namedtuple() derived class
我有一个名为 EasyUrl()
的 class 派生自 urlparse.Parseresult()
。 ParseResult()
在调用 urlparse.urlparse(url)
时被实例化,我在 EasyUrl()
中有一个静态方法将实例化的 ParseResult()
对象的 class 类型更改为 EasyUrl()
目的。我将 urlparse.urlparse()
函数和 class 类型转换包装成函数 parse_url()
.
这种功能背后的原因是我试图解决一个单独的问题,我不需要回答但想要一个,当 __new__
是时我得到 TypeError
在实例化过程中调用,这让我知道我的参数数量无效。
直接实例化 EasyUrl()
时收到错误
# snippet
url = 'whosebug.com'
url = EasyUrl(url)
# snippet end
Output:
TypeError: __new__() takes exactly 7 arguments (2 given)
ParseResult()
class 继承自 namedtuple()
.
从 urlparse 库中摘录
class ParseResult(namedtuple('ParseResult', 'scheme netloc path params query fragment'), ResultMixin):
__slots__ = ()
def geturl(self):
return urlunparse(self)
既然我已经描述了代码的一些功能,那么问题来了。我无法访问命名元组的 (ParseResult) 属性。我正在尝试为 ParseResult()
实现默认方案(如果它丢失的话)。
但是我无法访问 class 定义中的属性。
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://whosebug.com'
# Fails if statment, then attempts to set the variable,
# but error is raised: AttributeError: can't set attribute
url = 'whosebug.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
为什么不从头开始创建一个新的 class 并将所有属性从 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))
您现在可以根据需要向此 class 添加任何其他方法。
更新
namedtuple
是一个动态创建新类型的函数。顺便说一下,除非我们为 __getitem__()
添加一些代码,否则我们的 EasyURL
对象不会充当元组
ParseResult
不允许您更改 scheme
等属性,因此没有理由继承它。
我有一个名为 EasyUrl()
的 class 派生自 urlparse.Parseresult()
。 ParseResult()
在调用 urlparse.urlparse(url)
时被实例化,我在 EasyUrl()
中有一个静态方法将实例化的 ParseResult()
对象的 class 类型更改为 EasyUrl()
目的。我将 urlparse.urlparse()
函数和 class 类型转换包装成函数 parse_url()
.
这种功能背后的原因是我试图解决一个单独的问题,我不需要回答但想要一个,当 __new__
是时我得到 TypeError
在实例化过程中调用,这让我知道我的参数数量无效。
直接实例化 EasyUrl()
时收到错误
# snippet
url = 'whosebug.com'
url = EasyUrl(url)
# snippet end
Output:
TypeError: __new__() takes exactly 7 arguments (2 given)
ParseResult()
class 继承自 namedtuple()
.
从 urlparse 库中摘录
class ParseResult(namedtuple('ParseResult', 'scheme netloc path params query fragment'), ResultMixin):
__slots__ = ()
def geturl(self):
return urlunparse(self)
既然我已经描述了代码的一些功能,那么问题来了。我无法访问命名元组的 (ParseResult) 属性。我正在尝试为 ParseResult()
实现默认方案(如果它丢失的话)。
但是我无法访问 class 定义中的属性。
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://whosebug.com'
# Fails if statment, then attempts to set the variable,
# but error is raised: AttributeError: can't set attribute
url = 'whosebug.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
为什么不从头开始创建一个新的 class 并将所有属性从 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))
您现在可以根据需要向此 class 添加任何其他方法。
更新
namedtuple
是一个动态创建新类型的函数。顺便说一下,除非我们为__getitem__()
添加一些代码,否则我们的 ParseResult
不允许您更改scheme
等属性,因此没有理由继承它。
EasyURL
对象不会充当元组