English 中文(简体)
在不同的模块中使用一个类别
原标题:Use a class in the context of a different module

我想修改标准图书馆的一些班级,以使用一套不同的全球,使用该单元的其他班级。

Example

This example is an example only:

# module_a.py

my_global = []

class A:
    def __init__(self):
        my_global.append(self)

class B:
    def __init__(self):
        my_global.append(self)

例如,如果我通过<条码>A(<><>>>>>>>/代码>,就<条码>对<条码>上标的标的“<>>----全球,创建<条码>。 但是,现在,我希望创建一个新的模块,即进口<编码>B,并且从该模块进口的<编码>B> ,而不是从模块中进口到的“my_global

# module_b.py

from module_a import B

my_global = []

Related

我为解释我的问题而努力,这里是我以前尝试的,事实上,这些尝试提出了完全不同的问题:

Update0

  • The example above is only for illustration of what I m trying to achieve.
  • Since there is no variable scope for classes (unlike say, C++), I think a reference to a globals mapping is not stored in a class, but instead is attached to every function when defined.

Update1

要求提供标准图书馆的一个例子:

http://hg.python.org/index.html。 如果不对这一模块的所有类别进行改动,就无法改变这些全球。

问题回答

如果不影响到模块的所有其他用户,你可以改变全球,但你所说的“can>/em>的确是制作整个模块的私人复制件。

我相信你很熟悉sys.modules <,如果你从那里搬走一个模块,那么该模块就进口了,但老的标注器将继续这样做。 一旦再次进口,将制作新版模块。

解决你问题的办法可能好像:

import sys
import threading

# Remove the original module, but keep it around
main_threading = sys.modules.pop( threading )

# Get a private copy of the module
import threading as private_threading

# Cover up evidence by restoring the original
sys.modules[ threading ] = main_threading

# Modify the private copy
private_threading._allocate_lock = my_allocate_lock()

如今, 私人-翻新 全球与<代码>翻新完全分开。 洛克!

不用说,该模块是出于这种考虑撰写的,特别是如果有一个系统模块,例如<代码>,可读/代码”,你可能会遇到问题。 例如,threading._active本应包含所有可操作的校对,但通过这一解决办法,“_active 均不会有。 法典还可以吃你吃饭,放下你的住房等等。 严格试验。

Okay, here s a proof-of-concept that shows how to do it. Note that it only goes one level deep -- properties and nested functions are not adjusted. To implement that, as well as make this more robust, each function s globals() should be compared to the globals() that should be replaced, and only make the substitution if they are the same.

def migrate_class(cls, globals):
    """Recreates a class substituting the passed-in globals for the
    globals already in the existing class.  This proof-of-concept
    version only goes one-level deep (i.e. properties and other nested
    functions are not changed)."""
    name = cls.__name__
    bases = cls.__bases__
    new_dict = dict()
    if hasattr(cls,  __slots__ ):
        new_dict[ __slots__ ] = cls.__slots__
        for name in cls.__slots__:
            if hasattr(cls, name):
                attr = getattr(cls, name)
                if callable(attr):
                    closure = attr.__closure__
                    defaults = attr.__defaults__
                    func_code = attr.__code__
                    attr = FunctionType(func_code, globals)
                new_dict[name] = attr
    if hasattr(cls,  __dict__ ):
        od = getattr(cls,  __dict__ )
        for name, attr in od.items():
            if callable(attr):
                closure = attr.__closure__
                defaults = attr.__defaults__
                kwdefaults = attr.__kwdefaults__
                func_code = attr.__code__
                attr = FunctionType(func_code, globals, name, defaults, closure)
                if kwdefaults:
                    attr.__kwdefaults__ = kwdefaults
            new_dict[name] = attr
    return type(name, bases, new_dict)

在经过这一节选之后,我是really,奇怪为什么你需要这样做?

“如果不为模块的所有类别改动,就无法改变这些全球”。 这个问题的根源在于此,并用<全球<<>>>/代码>的变量对该问题作了很好的解释。 使用<代码>Globals,将其类别与这些全球物体连接起来。

在你 j忙寻找和mon包件时,在模块的单个类别内每使用一个全球变数,在只是为了你自己使用而重新实施该守则之前,你是否会进一步?

围绕“视力”在你情况下使用的唯一工作是mock。 Mock s TOP decorators/context Manager (或某种类似情况)可用来在某一特定物体的生期中勾销全球变量。 它在非常受控的单位测试范围内运作良好,但在任何其他情况下,我将不建议这样做,并考虑仅仅重新实施该守则以满足我的需求。

Globals are bad for exactly this reason, as I am sure you know well enough.

I d try to reimplement A and B (maybe by subclassing them) in my own module and with all references to my_global replaced by an injected dependency on A and B, which I ll call registry here.

class A(orig.A):

    def __init__(self, registry):
        self.registry = registry
        self.registry.append(self)

    # more updated methods

如果你正在制造所有阿丽亚娜事件,你就做了大量工作。 你们可能想制造一个工厂,躲避新的非专用参数。

my_registry = []
def A_in_my_registry():
    return A(my_registry)

If foreign code creates orig.A instances for you, and you would rather have new A instances, you have to hope the foreign code is customizeable with factories. If not, derive from the foreign classes and update them to use (newly injected) A factories instead. .... And rinse repeat for for the creation of those updated classes. I realize this can be tedious to almost impossible depending on the complexity of the foreign code, but most std libs are quite flat.

--

Edit: Monkey TOP TOP pind lib Code.

If you don t mind monkey patching std libs, you could also try to modifiy the original classes to work with a redirection level which defaults to the original globals, but is customizable per instance:

import orig

class A(orig.A):

    def __init__(self, registry=orig.my_globals):
        self.registry = registry
        self.registry.append(self)

    # more updated methods

orig.A = A

As before you will need to control creations of A which should use non "standard globals", but you won t have different A classes around as long as you monkey patch early enough.

如果你使用<3>,你可以分级B并重新定义<代码>_globals__的属性_init_。 类似方法:

from module_a import B

function = type(lambda: 0)  # similar to  from types import FunctionType as function , but faster
my_global = []


class My_B (B):
    __init__ = function(B.__init__.__code__, globals(),  __init__ ,  B.__init__.__defaults__, B.__init__.__closure__)

IMHO it is not possible to override global variables...





相关问题
Can Django models use MySQL functions?

Is there a way to force Django models to pass a field to a MySQL function every time the model data is read or loaded? To clarify what I mean in SQL, I want the Django model to produce something like ...

An enterprise scheduler for python (like quartz)

I am looking for an enterprise tasks scheduler for python, like quartz is for Java. Requirements: Persistent: if the process restarts or the machine restarts, then all the jobs must stay there and ...

How to remove unique, then duplicate dictionaries in a list?

Given the following list that contains some duplicate and some unique dictionaries, what is the best method to remove unique dictionaries first, then reduce the duplicate dictionaries to single ...

What is suggested seed value to use with random.seed()?

Simple enough question: I m using python random module to generate random integers. I want to know what is the suggested value to use with the random.seed() function? Currently I am letting this ...

How can I make the PyDev editor selectively ignore errors?

I m using PyDev under Eclipse to write some Jython code. I ve got numerous instances where I need to do something like this: import com.work.project.component.client.Interface.ISubInterface as ...

How do I profile `paster serve` s startup time?

Python s paster serve app.ini is taking longer than I would like to be ready for the first request. I know how to profile requests with middleware, but how do I profile the initialization time? I ...

Pragmatically adding give-aways/freebies to an online store

Our business currently has an online store and recently we ve been offering free specials to our customers. Right now, we simply display the special and give the buyer a notice stating we will add the ...

Converting Dictionary to List? [duplicate]

I m trying to convert a Python dictionary into a Python list, in order to perform some calculations. #My dictionary dict = {} dict[ Capital ]="London" dict[ Food ]="Fish&Chips" dict[ 2012 ]="...