NetworkX Graph 对象不可订阅
NetworkX Graph object not subscriptable
我试图在不输入的情况下猴子修补 NetworkX Graph 对象
networkx.Graph.method_name = method_name
对于我定义的每一个方法。我试过这个(最小版本):
import networkx
class _GraphExtended (networkx.Graph):
def is_nonnull(self):
return bool(self.nodes())
for key in _GraphExtended.__dict__:
nx.Graph[key] = _GraphExtended[key]
并且每个键都出现错误“'type' 对象不可订阅”。我如何使用循环猴子修补所有方法?
分析你目前的做法
您正在通过方括号使用下标表示法。通常,您会输入 my_object[key]
,它被翻译成 作为第一个近似值 * 到 my_object.__getitem__(key)
.
特别是,如果 type(my_object)
没有定义 __getitem__
属性,那么您实际上会得到一个错误,指出 type(my_object)
不可订阅。
在您的情况下,type(_GraphExtended) == type
成立。此外,type
class 没有定义任何 __getitem__
属性。因此,这就是您收到 type
不可订阅的错误消息的原因。
*为了完整起见,更准确的翻译应该是:object.__getattribute__(my_object, '__getitem__')(key)
.
你可能想要什么
您可能打算设置 networkx.Graph
对象的 'method_name'
属性。一般来说,这可以通过使用 setattr
内置函数来完成,如下所示:
setattr(networkx.Graph, key, value)
此外,_GraphExtended.__dict__
包含的键比您打算进行猴子补丁的键多得多。您也许可以过滤掉以双下划线开头和结尾的那些,但我既不相信这个过滤器在所有情况下都能正常工作,也不相信它与 Python.
向前兼容
猴子补丁的陷阱
首先,猴子补丁可能会破坏与 networkx 库的前向兼容性。不能保证 networkx 的未来版本会避免使用您选择用于猴子补丁的相同方法名称。
其次,猴子补丁会阻止您编写可重用的代码。其他开发人员不再可能重用您的便捷功能,除非他们自己对代码进行猴子修补,并且可能有无法预料的原因阻止这种情况发生。
实用建议
不要这样做。 我必须警告你,猴子修补库代码的风格很差,应该只在编程世界中用作最后的手段(例如,如果它要对业务收入或相关资源(如开发时间)产生积极且可衡量的影响)。
您希望解决的潜在问题是什么?我愿意跟进替代解决方案,解决您可能遇到的每个潜在问题。
此外,您是否考虑过定义包含辅助函数的辅助模块的简单方法,例如:
# Module graph_utils
def is_nonnull(graph):
return bool(graph.nodes())
其他注意事项
Python 已经有一个处理布尔上下文的约定:任何被认为是空的也应该被认为是假的。例如,根据 networkx 文档,Graph
class 定义了一个 __len__
方法,即 returns 节点数。由于 __len__
,Python 允许在需要 bool
的上下文中使用 Graph
对象。例如,
graph = networkx.Graph()
print(not graph) # Prints True iff len(graph) == 0
if graph:
print('Graph is nonnull.')
else:
print('Graph is null.')
我试图在不输入的情况下猴子修补 NetworkX Graph 对象
networkx.Graph.method_name = method_name
对于我定义的每一个方法。我试过这个(最小版本):
import networkx
class _GraphExtended (networkx.Graph):
def is_nonnull(self):
return bool(self.nodes())
for key in _GraphExtended.__dict__:
nx.Graph[key] = _GraphExtended[key]
并且每个键都出现错误“'type' 对象不可订阅”。我如何使用循环猴子修补所有方法?
分析你目前的做法
您正在通过方括号使用下标表示法。通常,您会输入 my_object[key]
,它被翻译成 作为第一个近似值 * 到 my_object.__getitem__(key)
.
特别是,如果 type(my_object)
没有定义 __getitem__
属性,那么您实际上会得到一个错误,指出 type(my_object)
不可订阅。
在您的情况下,type(_GraphExtended) == type
成立。此外,type
class 没有定义任何 __getitem__
属性。因此,这就是您收到 type
不可订阅的错误消息的原因。
*为了完整起见,更准确的翻译应该是:object.__getattribute__(my_object, '__getitem__')(key)
.
你可能想要什么
您可能打算设置 networkx.Graph
对象的 'method_name'
属性。一般来说,这可以通过使用 setattr
内置函数来完成,如下所示:
setattr(networkx.Graph, key, value)
此外,_GraphExtended.__dict__
包含的键比您打算进行猴子补丁的键多得多。您也许可以过滤掉以双下划线开头和结尾的那些,但我既不相信这个过滤器在所有情况下都能正常工作,也不相信它与 Python.
猴子补丁的陷阱
首先,猴子补丁可能会破坏与 networkx 库的前向兼容性。不能保证 networkx 的未来版本会避免使用您选择用于猴子补丁的相同方法名称。
其次,猴子补丁会阻止您编写可重用的代码。其他开发人员不再可能重用您的便捷功能,除非他们自己对代码进行猴子修补,并且可能有无法预料的原因阻止这种情况发生。
实用建议
不要这样做。 我必须警告你,猴子修补库代码的风格很差,应该只在编程世界中用作最后的手段(例如,如果它要对业务收入或相关资源(如开发时间)产生积极且可衡量的影响)。
您希望解决的潜在问题是什么?我愿意跟进替代解决方案,解决您可能遇到的每个潜在问题。
此外,您是否考虑过定义包含辅助函数的辅助模块的简单方法,例如:
# Module graph_utils
def is_nonnull(graph):
return bool(graph.nodes())
其他注意事项
Python 已经有一个处理布尔上下文的约定:任何被认为是空的也应该被认为是假的。例如,根据 networkx 文档,Graph
class 定义了一个 __len__
方法,即 returns 节点数。由于 __len__
,Python 允许在需要 bool
的上下文中使用 Graph
对象。例如,
graph = networkx.Graph()
print(not graph) # Prints True iff len(graph) == 0
if graph:
print('Graph is nonnull.')
else:
print('Graph is null.')