简体   繁体   中英

Function prints value but returns “None”

def findLineParam(sprotParam, pos):

    if line[:2] == sprotParam:
        start = pos
        while line[start] == " ":
            start += 1
        stop = start + 1 
        while stop < len(line) and not line[stop] in (" ", ";"):
            stop += 1
        print(line[start:stop]) # prints the correct value!
        return line[start:stop] # returns None? 

To briefly explain the function of the code is that it should take an input string (keyword), eg "ID" and find this on a line in a text file then it should find the first value after white space reading to next " " or ";" and return this. I can see that when I print the line, it returns exactly what I want but when I return it, it returns "None".

Whenever I change the "sprotParam" to an input list instead (*sprotParam) it does return the values but also an equal amount of "None" corresponding to the lines in the file, which I believe indicates, that it iterates and performs operations on all lines, which it shouldn't.

Code calling the function

try:
    file = input("Enter filename: ")
except IOError as e:
    print("That is not a recognised filename. Error given: " + str(e)) 
    sys.exit(1) # Close the program

with open(file, 'r') as infile:
    for line in infile:
        ident = findLineParam("ID", 2)

line isn't within the function's scope, so you need to pass it to the function as an argument:

def findLineParam(sprotParam, pos, line):
    if line[:2] == sprotParam:
        start = pos
        while line[start] == " ":
            start += 1
        stop = start + 1 
        while stop < len(line) and not line[stop] in (" ", ";"):
            stop += 1
        print(line[start:stop]) # prints the correct value!
        return line[start:stop] # returns None? 

with open(file, 'r') as infile:
    for line in infile:
        ident = findLineParam("ID", 2, line)

Update

Here is a simplified version of your code:

def findLineParam(sprotParam, file):
    for line in file.split(sprotParam):#split by parameter
        if line != '<':
            for item in line.split(): #split by whitespace
                if item != '=':
                    print(item)
                    return item

    raise Exception(f'No {sprotParam} parameters were found in the given file')

file = 'test.txt'
with open(file, 'r') as f:
    ident = findLineParam("ID", f.read())

Now, if you run this for test.txt :

<ID= 'foo'    > <div></div>
asdfnewnaf

It will return 'foo' .

if your function must return something, you should return a default value (you only are returning on a if statement, so if you don't matche this if, you return None) I know it's not solving you problem but it's better to get this ^^

As @NoxFly suggested all paths doesn't return.

def findLineParam(sprotParam, pos, line):
    ret = ''
    if line[:2] == sprotParam:
        start = pos
        while line[start] == " ":
            start += 1
        stop = start + 1 
        while stop < len(line) and not line[stop] in (" ", ";"):
            stop += 1
        print(line[start:stop]) # prints the correct value!
        ret = line[start:stop] # returns None? 
   return ret

with open(file, 'r') as infile:
    for line in infile:
        ident = findLineParam("ID", 2, line)

A much better approach will be to use regex instead of those while loops. for example the regex will find the value.

r"ID:([^(\s|;)]*)"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM