Python中的无意循环

时间:2015-11-30 18:19:12

标签: python debugging

我刚刚编写了下面的代码,而我遇到的问题是它会显示userInput中的所有print语句两次,然后给出错误AttributeError: 'function' object has no attribute 'input_voltage'。我对Python很新,所以任何指导都会非常感激!

userInput.py:

def InputParameters():
 import testSetup
 test_setup = testSetup.TestCombos
 print("Please input test parameters. Separate multiple test parameters with a comma:\n")
 complete_power_cycle = raw_input("Please select:\n  1. Complete power cycle including both test PC and SSD\n  2. Partial power cycle only including SSD\n")
 cycles = raw_input("Number of cycles: ")                                                                   
 rise_time = raw_input("Rise time: ")
 fall_time = raw_input("Fall time: ")
 overshoot_limit = raw_input("Overshoot voltage: ")
 overshoot_time = raw_input("Overshoot time: ")
 input_voltage = raw_input("Input voltage: ")
 ssd_off_Time = raw_input("Off time between SSD power cycles: ")
 pc_off_time = raw_input("Off time between PC power cycles (if partial power cycle selected, enter none): ")
 temperature = raw_input("Temperature: ")
 test_stop = raw_input("Stop test upon failure? Y/N\n")
 test_setup()

testSetup.py:

def TestCombos():
 import userInput                                                       
 param = userInput.InputParameters
 output = open('testParamFile.txt', 'w')

 #form combinations from test parameters

 for a in param.input_voltage:
    for b in param.overshoot_limit:
        for c in param.overshoot_time:
            for d in param.rise_time:
                for e in param.fall_time:
                    for f in param.temperature:
                        for g in param.ssd_off_time:
                            for h in param.cycles:
                                for i in param.pc_off_time:
                                    if param.complete_power_cycle == '1':
                                        param_list = [a,b,c,d,e,f,g,i,h]
                                        print(param_list)
                                        #output.write(param_list)
                                    elif param.complete_power_cycle == '2':
                                        param_list = [a,b,c,d,e,f,g,h]
                                        print(param_list)
                                        #output.write(param_list)

2 个答案:

答案 0 :(得分:1)

这里存在一些严重的设计问题,但您可以通过简化代码来实现。您不应试图同时获取所有参数组合,而应一次获得一个完整的集合并将它们添加到列表中,这样您就可以获得要使用的参数列表列表。

<强> userInput.py

import testSetup  # imports go on top of a file


def get_param_set():
    """
    Returns a list of parameters to be used for testing
    """
    input_messages = [
        "Please select:\n  1. Complete power cycle including both test PC and SSD\n  2. Partial power cycle only including SSD\n",
        "Number of cycles: ",
        "Rise time: ",
        "Fall time: ",
        "Overshoot voltage: ",
        "Overshoot time: ",
        "Input voltage: ",
        "Off time between SSD power cycles: ",
        "Off time between PC power cycles (if partial power cycle selected, enter none): ",
        "Temperature: ",
        "Stop test upon failure? Y/N\n"
    ]
    return [raw_input(message) for message in input_messages]

或者,您可以使用字典来更轻松地跟踪您的参数:

def get_param_set():
        """
        Returns a list of parameters to be used for testing
        """
        input_messages = {
            'complete_power_cycle': "Please select:\n  1. Complete power cycle including both test PC and SSD\n  2. Partial power cycle only including SSD\n",
            'cycles': "Number of cycles: ",
            'rise_time': "Rise time: ",
            'fall_time': "Fall time: ",
            'overshoot_limit': "Overshoot voltage: ",
            'overshoot_time': "Overshoot time: ",
            'input_voltage': "Input voltage: ",
            'ssd_off_Time': "Off time between SSD power cycles: ",
            'pc_off_time': "Off time between PC power cycles (if partial power cycle selected, enter none): ",
            'temperature': "Temperature: ",
            'test_stop': "Stop test upon failure? Y/N\n"
        }
        return {key: raw_input(value) for key, value in input_messages.items()}  # you may want to use int(raw_input()) since it looks like most of these will be numbers and 4 != '4'

现在您将拥有一个如下所示的字典:

{'cycles' '4', 'rise_time': '42', ...}

您只需知道参数名称而不是它可能变得混乱的索引就可以访问这些值:

>>> param_dict = get_param_set()
>>> param_dict.get('cycles', '0')  # this will give you the value at the key 'cycles' if it's in the dictionary or '0' if it's not.
>>> param_dict['cycles']  # this will also give you the value at the key cycles but it will raise an exception if that key hasn't been set.

<强> testSetup.py

import userInput


def test_combos():
    params = userInput.get_params()
    print(params)
    run_your_test_here(*params)

如果您想收集多组参数:

def test_combos(num_of_sets):
    param_sets = [userInput.get_params() for _ in range(num_of_sets)]
    print(params)
    for param_set in param_sets:
        run_your_test_here(*param_set)  # the star unpacks the list into positional arguments

列表解包的快速示例:

>>> def foo(a, b, c):
...     print(a)
...     print(b)
...     print(c)
...
>>> lst = [1,2,3]
>>> foo(*lst)
1
2
3

字典解包:

>>> def foo(a, b, c):
...     print(a)
...     print(b)
...     print(c)
...
>>> bar = {'a': 1, 'c': 3, 'b': 2}
>>> foo(**bar)
1
2
3

请注意,字典的顺序并不重要(字典是无序集合),只要字典映射中的键与参数名称匹配,它将被用作foo(a=1, b=2, c=3) < / p>

因此,您可以将列表传递给具有多个位置参数的函数。只要len(list)等于位置参数的数量并且它们的顺序相同,所有内容都会像你一个接一个地传递它们一样。 Read more here

在函数范围外分配的函数在函数范围之外是不可用的,除非您将它们返回并将它们保存到不同的变量中。他们考虑使用它们的方式将作为类属性。创建一个新类来运行测试当然是实现目标的另一种方式。

class TestCombo(object):
    def __init__(self):
        # there are better ways to do this but this is simplest to read
        self.complete_power_cycle = raw_input("...")
        self.cycles = raw_input("Number of cycles: ")                                                                   
        self.rise_time = raw_input("Rise time: ")
        self.fall_time = raw_input("Fall time: ")
        self.overshoot_limit = raw_input("Overshoot voltage: ")
        self.overshoot_time = raw_input("Overshoot time: ")
        self.input_voltage = raw_input("Input voltage: ")
        self.ssd_off_Time = raw_input("... ")
        self.pc_off_time = raw_input("...")
        self.temperature = raw_input("Temperature: ")
        self.test_stop = raw_input("...")

    def run_test_combo(self):
        # access class attributes like so
        foo = bar(self.cycles, self.rise_time, ...)
        print(self.test_stop)

使用课程:

>>> test_obj = TestCombo()
# your __init__ method will now run and collect all the inputs
>>> test_obj.test_stop
# will return whatever you set test_stop to be
>>> test_obj.run_test_combo()
# will run whatever code you put inside the method run_test_combo()

由于您似乎正在运行某种测试,因此您可以使用内置的unittest模块。

答案 1 :(得分:0)

我认为你可能误解了Python函数的工作原理。这些变量只存在于InputParameters函数内;如果你想在外面访问它们,你可以返回它们并将它们分配给TestCombos中的变量。

我建议您阅读Python范围,特别是关于functionsnamespaces