上下文感知功能



我在下面有一段代码:

 // 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()

如果您发现自己使用编号的变量名称(例如 v1v2v3(你需要立即停下来思考"我应该使用列表吗?">——在几乎所有情况下,答案都是"是"。

其他注意事项:

  • 要选择随机值,请列出可能的值(在本例中为 [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()

这将允许您添加到属性列表中。 这足以让你动起来吗? 在您更好地解释您的系统之前,我们无法提出更全面的解决方案。

最新更新