简体   繁体   English

如何在python中深度复制模块

[英]how to deepcopy a module in python

I found this issue in the thread: https://bugs.python.org/issue18195 我在帖子中找到了这个问题: https//bugs.python.org/issue18195

>>> from copy import deepcopy
>>> import types
>>> origin_types = deepcopy(types)
Traceback (most recent call last):
...
AttributeError: 'NoneType' object has no attribute 'update'

If I really want to deepcopy a module, what to do? 如果我真的想deepcopy一个模块,该怎么办?

Also, it must has some reason for team who did not implement this feature. 此外,对于未实现此功能的团队而言,它必须有一些原因。 Hope someone can explain the risk of doing this. 希望有人能解释这样做的风险。


[Updated] Here is my purpose [更新]这是我的目的

import os
from copy import deepcopy
from importlib import reload

def disabled_func(f):
    def inner(*args, **kwargs):
        return f(*args, **kwargs)
    return inner

class OSModuleCustomizer(object):

    def disable_method(self, os_method):
        setattr(os, os_method, disabled_func)

    def save_customized_module(self):
        self.custom_module = deepcopy(os)

    def get_customized_module(self):
        return self.custom_module

#original function
os.system("ls") # works

#modifying module
omc = OSModuleCustomizer()
omc.disable_method("system")
os.system("ls") # empty

#saving customized module
omc.save_customized_module();

#reload
reload(__import__("os"))
os.system("ls") # works

#reload saved customized-module
os = omc.get_customized_module()
os.system("ls") # empty

This answer shows how to clone a module. 这个答案显示了如何克隆模块。

Below is my solution with hacking sys.modules . 下面是我的黑客sys.modules解决方案。

import importlib
import os
import sys
from importlib import reload

class ModuleCustomizer:
    def __init__(self, fullname):
        self.custom_module = sys.modules[fullname]

    def disable_method(self, method):
        setattr(
            self.custom_module,
            method, 
            lambda *args, **kwargs: print(
                f'{self.custom_module.__name__}: {method} is disabled.')
        )

    def save_customized_module(self):
        fullname = self.custom_module.__name__
        spec = importlib.util.find_spec(fullname)
        clone = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(clone)
        sys.modules[fullname] = clone


    def get_customized_module(self):
        return self.custom_module

#original function
os.system('ls') # works

#modifying module
omc = ModuleCustomizer('os')
omc.disable_method('system')
os.system('ls') # disabled

#saving customized module
omc.save_customized_module()

#reload
os = reload(__import__('os'))
# In this case, below line works too.
# os = reload(sys.modules['os'])

os.system("ls") # works
omc.get_customized_module().system('ls') # disabled

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM