我在下面有一段代码:
// The only difference is grad
class TestOne(...):
def init(self):
self.input_one = tr.allocate( ..., grad = False)
self.input_two = tr.allocate( ..., grad = False)
class TestTwo(...):
def init(self):
self.input_one = tr.allocate( ..., grad = True)
self.input_two = tr.allocate( ..., grad = False)
class TestThree(...):
def init(self):
self.input_one = tr.allocate( ..., grad = False)
self.input_two = tr.allocate( ..., grad = True)
Test1 = TestOne()
Test2 = TestTwo()
Test3 = TestThree()
# definition of allocate. It is a wrapper of the PyTorch randn function
# https://pytorch.org/docs/stable/torch.html#torch.randn
def allocate(..., grad):
...
return torch.randn(..., require_grad=grad)
我想通过只实现一个类来减少重复的代码,但能够生成与上述代码相同的对象。
class Test(...):
// how to make it return different values?
def auto_set(self):
return False
def init(self):
self.input_one = tr.allocate( ..., grad = self.auto_set())
self.input_two = tr.allocate( ..., grad = self.auto_set())
Test1 = Test()
# grad of input_one and input_two will be `False, False`
Test2 = Test()
# grad of input_one and input_two will be `True, False`
Test3 = Test()
# grad of input_one and input_two will be `False, True`
这是一个大项目的一部分,所以我无法更改 init 函数的接口。可能有 N 个输入,需要 N + 1 个不同的类。这不是一个可扩展的实现,所以想要找到一个解决方案来解决这个问题。
PS:我之前的问题给别人带来了太多的困惑,所以我改变了它,希望澄清我真正想要拥有的东西。
只是在这里发布我的解决方案:
class Test(object):
init_counter = 0
num_variable = 0
def increase_init_counter(self):
Test.init_counter += 1
Test.auto_set_counter = 0
def auto_set(self):
if Test.init_counter == 0:
Test.num_variable += 1
return False
else:
print ("init_counter: {}, auto_set_counter: {}".format(Test.init_counter, Test.auto_set_counter))
Test.auto_set_counter += 1
if Test.init_counter == Test.auto_set_counter:
return True
else:
return False
def init(self):
self.A = self.auto_set();
self.B = False;
self.C = self.auto_set();
print ("A: {}, B: {}, C: {}".format(self.A, self.B, self.C))
=== Test
TestA = Test()
TestA.init()
for _ in range(TestA.num_variable):
TestB = copy.deepcopy(TestA)
TestB.increase_init_counter()
TestB.init()
如果您发现自己使用编号的变量名称(例如 v1
,v2
,v3
(你需要立即停下来思考"我应该使用列表吗?">——在几乎所有情况下,答案都是"是"。
其他注意事项:
- 要选择随机值,请列出可能的值(在本例中为
[True, False]
(并使用random.choice()
-
range()
可以列出 N 个值,我们可以用它来制作另一个随机选择列表(当您不理解[x for x in iterable]
语法时,请参阅"列表理解"(。 - 类将
__init__
作为构造函数,您不需要手动init
函数。 - 类应在其名称的开头使用大写字母。
法典:
from random import choice
class Test(object):
def __init__(self, num_values):
self.values = [choice([True, False]) for _ in range(num_values)]
def see(self):
print(self.values)
for _ in range(3):
test1 = Test(3)
test1.see()
打印类似以下内容:
[False, False, False]
[True, False, True]
[True, True, False]
让我们看看IIUYC...:
您可以做的是在类定义中添加一个全局变量,或者说更好的公共变量,该变量在实例化该类的新对象时会递增(并且删除它们时可能也会更好地递减(。
这将使您有机会根据之前已创建的对象数量实现不同的__init__()
行为。
想象一个像这样的测试类
class Test():
i = 0
def __init__(self):
Test.i += 1
def __del__(self):
Test.i -= 1
创建第一个对象后,公共计数器1
:
t1 = Test()
t1.i
1
创建第二个对象后,公共计数器2
:
t2 = Test()
t2.i
Out: 2
。在所有现有对象中,因为它是一个公共计数器:
t1.i
Out: 2
我认为您想要实现的一些示例实现:
class Test():
i = 0
def __init__(self):
self.A = bin(Test.i)[-1] == '1'
self.B = bin(Test.i)[-2] == '1'
Test.i += 1
def __del__(self):
Test.i -= 1
t1 = Test()
print(t1.i, t1.A, t1.B)
# 1 False False
t2 = Test()
print(t2.i, t2.A, t2.B)
# 2 True False
t3 = Test()
print(t3.i, t3.A, t3.B)
# 3 False True
首先,我怀疑你需要的是实例属性(类型每个对象中的变量(的list
。
class test(object):
def __init__(self):
self.v = []
# how to make it return different values?
def auto_set(self):
return False
def init(self):
self.v.append(self.auto_set())
def see(self):
print (self.v)
for _ in range(3):
test1 = test()
test1.init()
test1.see()
这将允许您添加到属性列表中。 这足以让你动起来吗? 在您更好地解释您的系统之前,我们无法提出更全面的解决方案。