使用IP地址作为参数的函数调用

1 投票
4 回答
3047 浏览
提问于 2025-04-18 14:43

我正在做一个抓取工具,用来检查文件传输的进度,这个工具是基于一个保存了IP地址的列表。当一个文件传输完成后,我想把这个IP地址从原来的列表中移除,并放到一个单独的列表里,这个列表叫“complete”。

开始的代码:

servers = {"10.10.10.1": "", "10.10.10.2": "", "10.10.10.3": ""}
skeys = servers.keys()
complete = []

def donewith(server):
    if server in skeys:
        complete.append("{0}".format(server))
        servers.pop("{0}".format(server))
        logging.info('Moved {0} to Complete list.'.format(server))
    else:
        logging.error('Unable to move \'{0}\' to Complete list.'.format(server))

想要的结果:

donewith(10.10.10.1)

servers = {"10.10.10.2": "", "10.10.10.3": ""}
complete = ["10.10.10.1"]

但我实际得到的是这个。

donewith(10.10.10.1)
File "<stdin>", line 1
donewith(10.10.10.1)
                ^
SyntaxError: invalid syntax

如果我用引号来调用这个函数,就会出现一个TypeError,提示需要一个整数。 我不太确定该怎么解决这个问题,因为看起来这个问题很简单。

关于引号解决方案的详细说明:

def check(server):
    #print "Checking {0}".format(server)
    logging.info('Fetching {0}.'.format(server))
    response = urllib2.urlopen("http://"+server+"/avicapture.html")
    tall = response.read() # puts the data into a string
    html = tall.rstrip()
    match = re.search('.*In Progress \((.*)%\).*', html)
    if match:
        temp = match.group(1)
        results = temp
        servers[server] = temp
        if int(temp) >= 98 and int(temp) <= 99:
            abort(server)
            alertmail(temp, server)
            donewith(server)
            logging.info('{0} completed.'.format(server))
        return str(temp)
    else:
        logging.error('Unable to find progress for file on {0}.'.format(server))
        return None

这个函数调用了donewith()函数,但如果函数里有引号,比如:donewith("server"),就会出问题。

举个例子:

def check(server):
     donewith("server")

def donewith(server)
     do_things.

check(server)

结果是……

check(10.10.10.3)
             ^
SyntaxError: invalid syntax

总是第三组数字里有个零……

4 个回答

0

试试这个

In [6]: def donewith(server):
...:         if server in skeys:
...:                 complete.append(server)
...:                 servers.pop(server)
...:                 logging.info('Moved {0} to Complete list.'.format(server))
...:         else:
...:                 logging.error('Unable to move \'{0}\' to Complete list.'.format(server))
...:

In [7]: donewith("10.10.10.1")

In [8]:

In [8]: servers
Out[8]: {'10.10.10.2': '', '10.10.10.3': ''}
1

你想要的效果现在是无法实现的,因为 10.10.10.1 不是一个字符串。Python看到点 . 后,会尝试把它当成浮点数来处理,但浮点数只能有一个小数点,所以错误信息指向了第二个点后面的数字。

要让它正常工作,你需要把参数作为字符串传递:

donewith("10.10.10.1")

servers = {"10.10.10.2": "", "10.10.10.3": ""}
complete = ["10.10.10.1"]

而且不仅在 donewith 中要这样做,在 check 中也要:

def check(server): # here server is variable name, not a string
    donewith(server)

def donewith(server)
    do_things.

check(server) # server = "10.10.10.1"
# or
check("10.10.10.1")

这是因为Python的工作方式,你需要用引号来声明字符串,否则它会把它当成数字(如果第一个字符是数字)或者变量名来处理。

1

关键是一个字符串。你应该这样做:

    donewith('10.10.10.1')
0

接着之前的话题,有些回答忽略了一点:一个函数不能用IP地址作为参数去调用另一个函数,因为IP地址中有很多点,这样就会让它变成不是字符串。即使在函数内部用func(str(ip))去调用,也没有效果。

我换了个思路,决定直接针对条目的索引,而不是条目的名称。

解决方案:

servers = {"10.10.10.1": "", "10.10.10.2": "", "10.10.10.3": ""}
skeys = servers.keys() # Creates list of dictionary keys (IP addresses)
["10.10.10.1", "10.10.10.2", "10.10.10.3"]

for i, j in enumerate(skeys): # Find the index
    if j == server:
        skeys.pop(i) # Pop the index.

servers = servers.fromkeys(skeys, "") # Recreates server dict from skeys.

撰写回答