设计一个黑盒子蟒蛇

时间:2018-03-27 18:12:01

标签: python

我想在python中有一个黑盒子

  • 输入是一个列表A.
  • 黑盒子有一个随机数字C,它是第一次调用黑盒子时随机选择的,并且在下次调用黑盒子时保持不变。
  • 基于列表A和数字C,输出是列表B.

我正在考虑将此黑匣子定义为一个功能,但问题是某个功能无法为下次调用保留所选的数字C.请注意,黑匣子的输入和输出如上所述,我们不能将C也作为输出,并将其用于下一次调用。有什么建议吗?

4 个答案:

答案 0 :(得分:4)

使它成为一个类,所以C将持续存在。

class BlackBox():
    def __init__(self):
        self.C = rand.randint(100)
        etc...

作为旁注,使用一些非常酷的Python功能......

您可以通过为新班级实施__call__()来调用此类的对象。

#inside the BlackBox class
def __call__(self, A):
    B = []
    #do something to B with A and self.C
    return B

然后您可以在主代码中使用它。

bb = BlackBox()
A = [1, 2, 3]
B = bb(A)

答案 1 :(得分:4)

  

问题是函数无法为下次调用保留所选的数字C.

在其他语言中可能也是如此,但在Python中却不是这样。 Python中的函数与其他函数一样,因此您可以在其上存储内容。这是这样做的最小例子。

import random

def this_function_stores_a_value():
    me = this_function_stores_a_value
    if 'value' not in me.__dict__:
        me.value = random.random()
    return me.value

这并不能直接解决您的列表问题,但它应该指向正确的方向。

附注:您还可以将持久数据存储在可选参数中,例如

def this_function_also_stores_a_value(value = random.random()):
    ...

但是,我不推荐这种方法,因为用户可以通过明确传递参数来篡改您的值。

答案 2 :(得分:2)

有很多方法可以存储函数的持久数据。它们都有它们的用途,但总的来说,首先出现的那些比后来出现的更有用。 (为了缩短时间,我解决的问题比你提出的问题稍微简单一些,但是如何适应它应该很明显。)

实例属性

class BlackBox:
    def __init__(self):
        self.C = rand.randint(100)
    def check(self, guess):
        return (guess - self.C) / abs(guess - self.C)

现在您可以创建一个或多个BlackBox()个实例,每个实例都有自己的随机数。

关闭变量

def blackbox():
    C = rand.random()
    def check(guess):
        return (guess - C) / abs(guess - C)
    return check

现在,您可以创建一个或多个check函数,每个函数都有自己的随机数。 (这与实例变量是双重的 - 也就是说,它具有相同的功能 - 但通常一个或另一个更具可读性。)

全局变量

def makeblackbox():
    global C
    C = random.randint(100)
def check(guess):
    return (guess - C) / abs(guess - C)

这样,整个程序只有一个黑盒子。这通常不是一个好的设计,这是“全局变坏”的原因之一。此外,它使用C变量来污染全局命名空间,除了check函数之外,对任何人都没有任何意义,这是“全局错误”的另一个原因。

功能属性

def makeblackbox():
    check.C = random.randint(100)
def check():
    return (guess - check.C) / abs(guess - check.C)

这相当于一个全局,因为你只能拥有一个黑盒子,但至少该变量隐藏在check函数上,而不是污染全局命名空间。

类属性

class BlackBox:
    C = rand.randint(100)
    @staticmethod
    def check(guess):
        return (guess - BlackBox.C) / abs(guess - BlackBox.C)

这再次等同于全局变量而不会污染全局命名空间。但它在函数属性方面有一个缺点 - 你创建一个没有有用实例的类通常会产生误导。

类属性2

class BlackBox:
    C = rand.randint(100)
    @classmethod
    def check(cls, guess):
        return (guess - cls.C) / abs(guess - cls.C)

这与前三个不同,您可以通过创建BlackBox的子类来创建新的黑盒子。但这很少是你真正想做的事情。如果您想要多个持久值,则可能需要实例。

答案 3 :(得分:1)

因为你在评论中提问。 这可能不是推荐的方式,但它很容易并且有效,所以我在这里添加它。

您可以使用全局变量来实现目标。

import random

persistant_var = 0

def your_func():
    global persistant_var
    if persistant_var:
        print('variable already set {}'.format(persistant_var))
    else: 
        print('setting variable')
        persistant_var = random.randint(1,10)

your_func()
your_func()

输出:

setting variable
variable already set 7

希望这很清楚。

enter image description here