Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过getattr抛出访问的绑定Python方法:";不接受任何参数(给定1个)“;_Python_Class_Getattr - Fatal编程技术网

通过getattr抛出访问的绑定Python方法:";不接受任何参数(给定1个)“;

通过getattr抛出访问的绑定Python方法:";不接受任何参数(给定1个)“;,python,class,getattr,Python,Class,Getattr,在绑定方法、继承和getattr之间的交互中发生了一些我不理解的奇怪的事情 我有一个目录设置,如: /a __init__.py start_module.py /b __init__.py imported_module.py 导入的_module.py包含许多类对象,其中一个是以下形式: class Foo(some_parent_class): def bar(self): return [1,2,3] start_module.py中的函数使用in

在绑定方法、继承和getattr之间的交互中发生了一些我不理解的奇怪的事情

我有一个目录设置,如:

/a
__init__.py
start_module.py
  /b
  __init__.py
  imported_module.py 
导入的_module.py包含许多类对象,其中一个是以下形式:

class Foo(some_parent_class):
    def bar(self):
       return [1,2,3]
start_module.py中的函数使用inspect获取表示导入的_module.py中的类的字符串列表。“Foo”是这些字符串中的第一个。目标是使用该字符串和getattr在start_module.py中运行bar*

为此,我使用表单的start_模块中的代码:

for class_name in class_name_list:
  instance = getattr(b.imported_module, class_name)()
  function = getattr(instance, "bar")
  for doodad in [x for x in function()]:
     print doodad 
它确实成功地开始迭代列表理解,但是在第一个字符串“bar”上,我得到了一个奇怪的错误。尽管bar是一个绑定方法,而且据我所知,它期望一个Foo实例作为参数,但我被告知:

TypeError:bar()不接受任何参数(给定1个)

这使得我对function()的调用似乎正在传递Foo实例,但代码不希望收到它

我真的不知道这里发生了什么,也无法通过查看Google和Stack Overflow解析出一个解释。双重getattr是否导致了一些奇怪的交互?我对Python中类对象的理解是否过于模糊?我很想听听你的想法

*为了避免这种反模式,真正的最终目标是让start_module.py自动拥有对名称栏所有方法的访问权限,这些方法跨各种类,类似于导入的_module.py中的Foo。我这样做是希望避免让我的继任者维护一个可能是大量类似Foo的类的列表


下面回答:我认为这里最大的收获是,inspect非常有用,如果您遇到的bug有一个共同的原因,那么在继续搜索其他可能性之前,请确保您已经排除了这一点。在本例中,我忽略了一个事实,即由于最近对文件结构进行了编辑,我正在查看的具有正确代码的模块可能不是正在导入的模块。

类方法有一个基本上自动传递的
self
参数。它只是调用方法的类实例。您不需要传递另一个参数。

类方法有一个基本上自动传递的
self
参数。它只是调用方法的类实例。您不需要传递另一个参数。

因为您发布的示例代码是错误的,我猜您在某处有另一个带有Foo类的模块-可能
bar
是这样定义的

class Foo(object):
    def bar():   # <-- missing self parameter
        return [1,2,3]
类Foo(对象):
def bar():#>>Foo().bar()
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:bar()不接受任何参数(给定1个)

由于您发布的示例代码是错误的,我猜您在某处有另一个带有Foo类的模块-可能
bar
是这样定义的

class Foo(object):
    def bar():   # <-- missing self parameter
        return [1,2,3]
类Foo(对象):
def bar():#>>Foo().bar()
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:bar()不接受任何参数(给定1个)

我无法重现您遇到的错误。下面是我尝试从Python shell运行的一个简短、自包含的可编译示例:

>>> class Foo(object):
    def bar(self):
        print("Foo.bar!")

>>> import __main__ as mod
>>> cls = getattr(mod, "Foo")
>>> inst = cls()
>>> func = getattr(inst, "bar")
>>> func()
Foo.bar!

也许您可以尝试将基于
的代码修改为类似于此示例的代码,看看哪里出了问题。

我无法重现您得到的错误。下面是我尝试从Python shell运行的一个简短、自包含的可编译示例:

>>> class Foo(object):
    def bar(self):
        print("Foo.bar!")

>>> import __main__ as mod
>>> cls = getattr(mod, "Foo")
>>> inst = cls()
>>> func = getattr(inst, "bar")
>>> func()
Foo.bar!

也许您可以尝试将基于
inspect
的代码改编成这样的示例,看看哪里出了问题。

return=[1,2,3]
不是有效的Python。请确保您发布的是您正在使用的实际代码。为
Foo
创建一个元类可能是一个更好的主意,该元类可以“注册”所有
bar
,例如,将它们存储在列表中。很抱歉。修好它。我以一种非常简单的形式添加了类描述,以使其易读,并意外地插入了一个额外的字符。我同意gnibbler的观点。这根本不能解决问题的要点,但是在[x for x in function()]
中对doodad的列表理解是完全不必要的。只需在函数()中为doodad使用
return=[1,2,3]
不是有效的Python。请确保您发布的是您正在使用的实际代码。为
Foo
创建一个元类可能是一个更好的主意,该元类可以“注册”所有
bar
,例如,将它们存储在列表中。很抱歉。修好它。我以一种非常简单的形式添加了类描述,以使其易读,并意外地插入了一个额外的字符。我同意gnibbler的观点。这根本不能解决问题的要点,但是在[x for x in function()]中对doodad的列表理解是完全不必要的。只需在函数()中为doodad使用
!有问题的调用是function(),它没有获取另一个参数。有问题的调用是function(),它没有获取另一个参数。我希望是这样。我只是后退了一步,再次仔细检查了一下,bar和它覆盖的函数都用self-include编码。对于示例代码,很抱歉。@TimWilder:(1)在
for
循环显示它应该显示的代码之前,
print inspect.getsource(函数)
?(2) 在
python-tt
下运行时,您的代码是否工作(以排除由于空格不一致而可能出现的缩进错误)?(3) 如果没有,那么我想你必须建造一个。我明天去看看。很好的建议。问题是在我昏昏欲睡的时候,我移动了imported_module.py,并用start_module导入了移动的副本。我还在编辑那本旧书。DSM的建议