如何使用python';要正确地实例化嵌套类,请使用s\uu import\uu()和getattr()?
我在模块xyz中有以下代码:如何使用python';要正确地实例化嵌套类,请使用s\uu import\uu()和getattr()?,python,python-import,instantiation,inner-classes,Python,Python Import,Instantiation,Inner Classes,我在模块xyz中有以下代码: Class Outer: Class Nested: pass 我可以成功地实例化Outer对象,如下所示 module = __import__("xyz", fromlist=['']) the_class = getattr(module, "Outer") instance = the_class() 但是,当我将“Outer”替换为“Outer.Nested”时,我得到: AttributeE
Class Outer:
Class Nested:
pass
我可以成功地实例化Outer
对象,如下所示
module = __import__("xyz", fromlist=[''])
the_class = getattr(module, "Outer")
instance = the_class()
但是,当我将“Outer”
替换为“Outer.Nested”
时,我得到:
AttributeError:模块“xyz”没有外部属性。嵌套的
如何才能做到这一点
我也许应该澄清一下,上面的代码用于实例化在运行时之前类型未知的类。显然,我不是在寻找
instance=Outer.Nested()
两种方法,假设您有一个表示属性访问的字符串和一个嵌套对象:
>>> from types import SimpleNamespace
>>> module = SimpleNamespace(foo=SimpleNamespace(bar=SimpleNamespace(baz='tada!')))
>>> module
namespace(foo=namespace(bar=namespace(baz='tada!')))
第一种方法是通过拆分并在循环中使用getattr
(甚至,reduce
!)自己解析字符串:
这相当于:
>>> result = module
>>> for attr in "foo.bar.baz".split("."):
... result = getattr(result, attr)
...
>>> result
'tada!'
或者一次性使用内置的functools.attrgetter
factory函数:
>>> import operator
>>> operator.attrgetter("foo.bar.baz")(module)
'tada!'
有两种方法可以做到这一点,假设您有一个表示属性访问的字符串和一个嵌套对象:
>>> from types import SimpleNamespace
>>> module = SimpleNamespace(foo=SimpleNamespace(bar=SimpleNamespace(baz='tada!')))
>>> module
namespace(foo=namespace(bar=namespace(baz='tada!')))
第一种方法是通过拆分并在循环中使用getattr
(甚至,reduce
!)自己解析字符串:
这相当于:
>>> result = module
>>> for attr in "foo.bar.baz".split("."):
... result = getattr(result, attr)
...
>>> result
'tada!'
或者一次性使用内置的functools.attrgetter
factory函数:
>>> import operator
>>> operator.attrgetter("foo.bar.baz")(module)
'tada!'
以@juanpa.arrivillaga的答案为基础(但解释原因):
类和模块在Python中被视为对象。因此,当您在模块中声明一个类时,该类是该模块的一个属性;当您声明内部类时,内部类是外部类的属性,而不是模块的属性。当您将
“Outer.Nested”
交给模块的getattr
时,您需要模块的属性,因此属性的名称中有一个
。与属性的属性不完全相同。Python的解释器在解析时会执行“属性的属性”,因此您会感到困惑。以@juanpa.arrivillaga的答案为基础(但解释原因):
类和模块在Python中被视为对象。因此,当您在模块中声明一个类时,该类是该模块的一个属性;当您声明内部类时,内部类是外部类的属性,而不是模块的属性。当您将“Outer.Nested”
交给模块的getattr
时,您需要模块的属性,因此属性的名称中有一个
。与属性的属性不完全相同。Python的解释器在解析时会执行“属性的属性”,因此您会感到困惑。
我也许应该澄清一下,上面的代码用于实例化在运行时之前类型未知的类。显然,我不是在寻找instance=Outer.Nested()
。
您的意思是直到运行时才知道名称吗?Python中的所有类型都是在运行时确定的
如果是这样,您也可以做一个奇特但常见的技巧,调用方可以在运行时提交类型
#xyz.py
def get_实例(_类):
返回_类()
未知第三方
外部类别:
类嵌套:
通过
#main.py
从xyz导入获取_实例
导入未知的第三方
instance=get\u instance(未知的第三方\u.Outer.Nested)
您永远不需要知道要运行的代码要交给什么——这是由您的用户/客户在运行时决定的
研究Python使用@
作为语法糖的原因,找出这一现象如此普遍的原因。
我也许应该澄清一下,上面的代码用于实例化在运行时之前类型未知的类。显然,我不是在寻找instance=Outer.Nested()
。
您的意思是直到运行时才知道名称吗?Python中的所有类型都是在运行时确定的
如果是这样,您也可以做一个奇特但常见的技巧,调用方可以在运行时提交类型
#xyz.py
def get_实例(_类):
返回_类()
未知第三方
外部类别:
类嵌套:
通过
#main.py
从xyz导入获取_实例
导入未知的第三方
instance=get\u instance(未知的第三方\u.Outer.Nested)
您永远不需要知道要运行的代码要交给什么——这是由您的用户/客户在运行时决定的
研究Python使用
@
作为语法糖的原因,找出这一现象如此普遍的原因。因此,只需应用getattr
两次,类似于outer,nested=“outer.nested”.split('.');klass=getattr(getattr(模块,外部),嵌套)
或者,使用将与嵌套属性一起工作的操作符.attrgetter
access@juanpa. 没错!非常感谢。我刚刚用get_class=operator.attrgetter('Outer.Nested')替换了getattr
行;_class=get_class(模块)
非常有效。我觉得我应该投票,把你的答案标为正确答案。如果你想发布答案,就这样做。所以,只需应用两次getattr
,比如outer,nested=“outer.nested”。split('.');klass=getattr(getattr(模块,外部),嵌套)
或者,使用将与嵌套属性一起工作的操作符.attrgetter
access@juanpa. 没错!非常感谢。我刚刚用get_class=operator.attrgetter('Outer.Nested')替换了getattr
行;_class=get_class(模块)
非常有效。我觉得我应该投票,把你的答案标为正确答案。如果你想在网站上发布答案,我会这样做。谢谢继续。谢谢