0

当前场景:

我有一组类,它们都context在构造函数中使用一个公共参数,并且所有类都继承自一个公共基础。

class base:
    def common_method(self):
        pass

class a(base):
    def __init__(self,context, aa):
        pass

class b(base):
    def __init__(self, context, bb):
        pass

# ...

class z(base):
    def __init__(self, context, zz):
        pass

主要用途:

context = get_context_from_some_method()

A = a(context, 1)
B = b(context, 2)
C = c(context, 3)
D = d(context, 4)
.
.
.
Z = z(context, 26)

问题:

  • 是否有一种巧妙的方法可以context隐式地提供给所有类?
  • 我们有一个共同的基类,但我没有看到一种明显的方法来让它为所有类设置上下文。
  • 可以假设我想保持所有类实例通用的上下文。
  • 只是一个随机的想法 - 元类可以以某种方式提供帮助吗?

我知道这看起来很傻,但我只是想以某种方式摆脱冗余,以便我可以以某种方式设置全局上下文并专注于我的对象。

请建议一些方法?

**更新问题**

我无法在基类中设置上下文,因为这是在 Web 应用程序中使用的。因此,许多具有不同上下文的页面将使用类结构。所以,如果我在 base 中设置了一个上下文,那么它将与另一个使用相同 base 的网页实例设置的上下文冲突。因为,在 Web 应用程序中,所有上述类都将在所有页面的内存中。

4

4 回答 4

2

编辑:如果您不想/不能使用类变量,最好的办法是使用工厂函数。要么使其成为基类上的静态方法,要么使其成为模块级函数。

def make_instances(context, *instances):
    return [cls(context, *args) for cls, args in instances]

A, B, ..., Z = make_instances(get_context_from_some_method(), 
                 (a, (1,)), (b, (2,)), ..., (z, (26,)))

# or
instances = make_instances(get_context_from_some_method(), 
             zip(list_of_subclasses, ((x,) for x in range(1, 27))))

或者,我不知道这是否适用于您的情况,只需使用模块级全局变量:

class z(base):
    def __init__(self, zz):
        self.zz = zz
        self.context = context

context = 'abc'
Z = z(26)

除了使用其他答案中的类变量的建议之外,我建议您将上下文复制到实例上,以便您以后可以更改上下文而不会影响已创建的实例。

class base:
    context = None # if you want to be able to create without context.
    # just omit the previous line if you want an error
    # when you haven't set a context and you try to instantiate a subclass

class a(base):
    def __init__(self, aa):
        self.aa = aa
        self.context = self.context # sets an instance variable
        # so the class variable can be changed

class b(base):
    def __init__(self, bb):
        self.bb = bb
        self.context = self.context

base.context = 'context'

A = a(1)
B = b(2)

base.context = 'newcontext'

print A.context # context
于 2012-03-22T02:21:50.673 回答
1

您可以使用类变量:

base.context = 'context'
A = a(1)
B = b(2)
#...
于 2012-03-22T02:17:12.857 回答
-1

消除冗余的方法是识别重复的模式,并将模式分解为一些单独的代码位。

不确定这是否是您的真实代码,但从您的示例来看,模式是您正在以类似的方式实例化一大堆类。即使您从 type 所需的每一行中删除了 9 个字符context,,您仍在执行以下操作:

A = a(1)
B = b(2)
C = c(3)
...

这会让我发疯。冗余的问题不在于打字,而是如果你想改变它(比如你想从 0 开始,或者你想为每个类添加一个额外的参数,或者其他什么)你必须改变每一行.

所以我宁愿做这样的事情:

classes = [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z]
instances = [cls(context, i) for i, cls in enumerate(classes, 1)]

在这里,我的代码清楚地表明我正在实例化一大堆类,并且我将上下文传递给每个类,以及从 1 到我拥有的类数的整数(每个类都增加)。并且很容易独立决定更改类列表是什么,或者我要传递给每个类的内容。

这确实意味着我的实例的名称类似于instances[0]andinstances[13]而不是Aand N。也有一些方法可以解决这个问题,但我发现很少实例化一组事物,然后将它们用作独立的个体事物而不是集合。

于 2012-03-22T02:45:09.143 回答
-2

您应该将context定义为base的类属性。修改您的示例将是:

class base:

    context = None

    def common_method(self):
        pass

class A(base):
    def __init__(self, aa):
        pass

class B(base):
    def __init__(self, bb):
       pass

.
.
.

class Z(base):
    def __init__(self, zz):
        pass

base.context = get_context_from_some_method()
A = a(1)
B = b(2)
Z = z(3)    

所有 A、B 和 Z 实例共享相同的上下文属性。

于 2012-03-22T02:20:48.073 回答