有关使用修饰功能重新绑定名称的问题

时间:2018-10-25 07:00:32

标签: python python-2.7

我有以下情况:

# module_1.py

import compiled_c_module as cm

cm.function_1 = decorate(cm.function_1) # decorate is just a decorator function

然后在主要(或另一个包含模块)中,我有以下内容:

import compiled_c_module as main_cm

main_cm.function_1() # Has the expected default effect of function_1

import module_1

main_cm.function_1() # Has the effect of the decorated version of function_1

我希望函数的修饰版本仅在module_1的范围内适用。

我意识到解决此问题的一个显而易见的解决方案是将函数的修饰版本简单地分配给模块范围内的局部变量(例如,module_1中的“ my_decorated_func”),但是我特别希望可以在模块中对函数的修饰后的版本“照常”调用,同时在其他位置保持其默认状态。

2 个答案:

答案 0 :(得分:0)

如何在您的模块中使用它?以numpy为例:

class AttrDict(dict):
    def __getattribute__(self, attr):
        return self[attr]
    def __setattr__(self, attr, value):
        self[attr] = value

import numpy as np
np = AttrDict(np.__dict__)
np.sin = lambda x: x
np.sin(3) # Outputs 3 instead of 0.141

基本上,module(例如numpy)是python中的(通常是唯一的)对象,而变量名"numpy""np"是对该对象的引用。修改"numpy"时,您将影响唯一的对象,这将影响使用numpy的其他所有对象。

通过使用dict(np.__dict__),创建了numpy模块的浅层“副本”,您可以在其中自由修改任何内容(在第一级),而不会影响其他任何内容。 AttrDict基本上是一种奇妙的dict,您可以使用np.sin之类的语法代替np['sin']

请注意,由于这是一个浅表副本,因此您无法修改np.linalg.norm之类的“第二级”功能(请注意两个点),否则仍要修改全局模块。如果愿意,请遵循相同的规则并创建np.linalg

的副本

这不会影响numpy的全局定义,这意味着在此模块之外使用numpy不会受到影响。您也可以通过使用numpy

强制在该模块之外使用此模块的module.np

答案 1 :(得分:0)

  

我希望函数的修饰版本仅在module_1的范围内适用。

那就不要简单地重新绑定cm.function_1

# module_1.py

import compiled_c_module as cm
function_1 = decorate(cm.function_1) # decorate is just a decorator function

# then use `function_1` instead of `cm.function_1`