Python Integer类型检查函数输出不一致

时间:2017-05-05 18:41:56

标签: python

我创建了一个模拟标记/扫描垃圾收集算法的小程序。在大多数情况下,它完全有一个例外:我的自定义is_int()函数,用于区分mem_block->mem_block的引用和pointer_variable->mem_block的引用(因为pointer_variable名称可以& #39; t是一个整数)当True在运行整个程序时传递给它

时无法返回0

当我在Python交互模式下运行该函数时,正确运行is_int(0)会返回True。但是在运行整个程序时,if is_int(x)/else会在x == 0时将我转储到else分支中,但我无法找出原因。

以下是源代码和一些演示情况的屏幕截图,最相关的代码块用"#问题代码"表示:

import argparse
import re
import sys

class MemoryObject():
    def __init__(self):
        self.marked = 0
        self.references = []  # list of <MemoryObject> references

def arg_parse():
    # Sets up a parser object for handling arguments passed to the program
    parser = argparse.ArgumentParser(description='Some description')
    parser.add_argument('filename', help='Filename parameter for input file')
    return parser.parse_args()

# PROBLEM CODE
def is_int(s):
    # Determines if the given variable contains only an integer value
    # Primarily used to distinguish memory-blocks from named 
    # pointer variables
    if int(s): 
        return True
    elif s == 0: 
        return True
    else:
        return False
# /PROBLEM CODE

def node_trace(current_node, node_dict):
    # This function recursively simulates the "mark" phase of
    # Mark/Sweep G.C. using a dictionary of <MemoryObject>
    # each element therin containing its list of references
    #
    # Each node traversed is marked, and the function returns
    # if the node has already been checked
    #
    # This function assumed the inital call was passed the RootMemoryBlock
    # as it's starting point, which garuntees only accessible memory will
    # be marked since RootMemoryBlock only references pointers which 
    # in turn, by definition, only reference chains of accessible memory

    if current_node.marked == 1:
        return
    else:
        current_node.marked = 1

        for node in current_node.references:
            node_trace(node, node_dict)


def get_nodes():
    # This function creates a dictionary of memory-blocks and named 
    # pointer-variables ncluding a "RootMemoryBlock" that hold the  
    # pointer-variables. The number of memory blocks/variables is
    # determined by the contents of the input file.
    # 
    # Each object is stored in the dictionary as a <MemoryObject>
    #
    # The contents of the input file are then used to determine all references
    # between variables->blocks and blocks->blocks, with the only object 
    # referencing named-variables being the RootMemoryBlock. The format
    # of the file garuntees that memory_blocks are listed as integers, and
    # variables as strings that start with either a letter or an underscore '_'
    # 
    # is_int is therefor used to determing if an object is a variable or a
    # memory-block when populating the reference lists for the elements
    # of the <MemoryObject> dictionary
    #
    # Each object's reference list is stored in its <MemoryObject>::references
    # as a list of references to <MemoryObject>
    #
    # The dictionary is then passed into the node_trace function along with the 
    # RootMemoryBlock <MemoryObject> which recursively performs the 
    # "mark" phase of Mark/Sweep G.C.
    #
    # Finally a new dictionary is created and JUST the info for the 
    # memory-blocks (not variables, or the RootBlock) is copied into it.
    #
    # That dictionary is then returned to the calling function.
    node_pointers = []
    node_dict = {}
    args = arg_parse()
    input_file = args.filename

    with open(input_file) as in_file:
        node_count = 0
        for line in in_file:
            if node_count == 0:
                node_count = int(line)
            else:
                split_line = line.rstrip()
                split_line = re.split(r'[,]', split_line)
                node_pointers.append([split_line[0], int(split_line[1])])

    root_node_key = node_count
    array_size = node_count + 1
    for i in range (array_size):
        node_dict[i] = MemoryObject()

    # The format of the input file garuntees that each item will
    # describe a link of the form [source, target]
    SOURCE = 0  # The source of a reference link 
    TARGET = 1   # The target of a reference link

    for item in node_pointers:
    # PROBLEM CODE
        if is_int(item[SOURCE]):        
            node_dict[int(item[SOURCE])].references.append(node_dict[item[TARGET]])
        else:
            if item[SOURCE] not in node_dict.keys():
                node_dict[item[SOURCE]] = MemoryObject()

            node_dict[item[SOURCE]].references.append(node_dict[item[TARGET]])
            node_dict[root_node_key].references.append(node_dict[item[SOURCE]])
    # /PROBLEM CODE
    node_trace(node_dict[root_node_key], node_dict)

    node_dict_final = {}

    for element in node_dict.keys():
        if is_int(element) and element != root_node_key:
            node_dict_final[element] = node_dict[element]

    return node_dict_final


def print_result(message, value, nodes):
    # Displays the results of the mark/sweep algorithm
    # as stored in the dictionary "nodes"
    #
    # Prints all marked nodes if value == 1
    # Prints all reclaimed nodes if value == 0
    print(message)
    for element in nodes.items():
        if element[1].marked == value:
            if is_int(element[0]):
                print(element[0])


def main():
    # Entry Point function. Calls get_nodes which processes
    # the input_file, then runs the simluated mark/sweep
    # algorithm.
    #
    # It then displays the returned results of the mark/sweep

    nodes = get_nodes()
    print_result('\nMarked: ', 1, nodes)
    print_result('\nReclaimed: ', 0, nodes)
    print()


if __name__ == '__main__':
    main()

截图:

Interactive Mode

Running program with no references from 0th mem_block

Running program with references from 0th mem_block

1 个答案:

答案 0 :(得分:0)

在函数is_int()中,行:

elif s == 0

需要更改为

elif int(s) == 0

正确评估输入,因为参数是一个字符串,包含从文件读入的整数或变量名。这在任何非零整数的if情况下都是隐式处理的,但需要在elif零的情况下再次完成。