目前的情景:
我有一组在构造函数中都采用公共参数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中设置了一个上下文,那么它将与将使用相同基础的另一个网页实例设置的上下文冲突。因为,在Web应用程序中,所有上述类都将在所有页面共有的内存中。
答案 0 :(得分: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)
除了从其他答案中使用类变量的建议之外,我建议您将上下文复制到实例,以便以后可以更改上下文而不影响已创建的实例。< / p>
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
答案 1 :(得分:1)
您可以使用类变量:
base.context = 'context'
A = a(1)
B = b(2)
#...
答案 2 :(得分:-1)
消除冗余的方法是识别重复的模式,并将模式分解为一些单独的代码。
不确定它是否是您的真实代码,但从您的示例来看,模式是您以类似的方式实例化一大堆类。即使您从键入context,
所需的每一行中删除了9个字符,您仍然会这样做:
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]
和instances[13]
,而不是A
和N
。也有方法,但我发现很少实例化一组东西,然后将它们用作独立的个体而不是集合。
答案 3 :(得分:-2)
您应该将上下文定义为 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实例共享相同的上下文属性。