草庐IT

python - 在 python 中,我们可以在(其他)用户代码执行之前跟踪模块级分配吗?

coder 2023-08-25 原文

我正在开发一种工具,该工具将受益于从 python 中跟踪对给定对象的所有引用的能力。

具体来说,我想制作一个可以替换给定类型的所有模块级属性的测试替身系统。例如,假设以下代码在模块 c 中:

from a import b

如果 a 是一个模块,b 是对名为 a.b 的对象的引用,但它是一个独立引用。如果我的测试双系统稍后替换 a.b,c.b 仍将引用原始对象。

我想让我的工具跟踪 a.b 到别名的所有分配,但模块级别名对我的目标大有帮助。

打个比方,我想要覆盖Module.__setattribute__:

def __setattribute__(self, name, value):
    if isinstance(value, interesting_types):
        # remember this use of the interesting object and call super for normal processing.

假设我可以在加载可能被跟踪的模块之前加载我的代码。

最佳答案

这种事情可能对你有用。首先,一些代码:

a.py

b = 42
# other module definitions

fakery.py

class Fakery(object):
    def __init__(self, mod):
        self.module = __import__(mod)
        import sys
        sys.modules[self.module.__name__] = self

    def __getattr__(self, name):
        print "__getattr__ called with '%s'" % name
        result = getattr(self.module, name)
        if name == 'b':
            result += 1
        return result

例子

>>> import fakery
>>> fakery.Fakery('a')
<fakery.Fakery object at 0x109007110>
>>> from a import b
__getattr__ called with '__path__'
__getattr__ called with 'b'
>>> print b
43
>>> import a
>>> print a
<fakery.Fakery object at 0x109007110>

您所要做的就是修改 Fakery类做任何你想做的事。在这种情况下,我只是将 1 添加到 ab .

我希望大家清楚这是如何工作的,但这里有一个简短的解释。

当一个模块被导入时,它的记录被塞进sys.modules .当你实例化一个 Fakery对象,它所做的是按名称导入模块(使用 __import__ ),然后替换该模块在 sys.modules 中的条目与自己。

Python只导入一次模块,将导入的模块存储在sys.modules中.第一次导入后的每次导入都会返回 sys.modules 中的条目。 Fakery对象将自身插入sys.modules['a'] ,取代真正的模块。所有后续 import afrom a import <whatever>语句现在指向 Fakery 的一个实例.因为它只是一个类,所以您可以使用魔术方法或元编程来做各种疯狂的事情。

__getattr__很方便,因为当请求的属性不存在时会调用它。

关于python - 在 python 中,我们可以在(其他)用户代码执行之前跟踪模块级分配吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22896969/

有关python - 在 python 中,我们可以在(其他)用户代码执行之前跟踪模块级分配吗?的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  5. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  6. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  7. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  8. ruby-on-rails - Rails 源代码 : initialize hash in a weird way? - 2

    在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has

  9. ruby - 我可以使用 Ruby 从 CSV 中删除列吗? - 2

    查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html

  10. ruby - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

    我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的

随机推荐