1

それで、私は最近IRCボットに取り組んでいます。スパム対策機能の一部として誰かが最後に何かをした時間を保存します。これは、RPL_NAMREPLYを使用するように移動したWHO応答のユーザーのリストを初期化するために使用されていました。

それはほとんど動作します。しかし、私には非常に奇妙に見える問題があります。

import time

# ...

    def irc_unknown(self, prefix, command, params):
        """Handle packets that aren't handled by the library."""

        # Prefix: asimov.freenode.net
        # Command: RPL_BANLIST
        # Params: ['MCBans_Testing', '#mcbans-test', 'a!*@*', 'gdude2002!g@unaffiliated/gdude2002', '1330592882']

        self.runHook("unknownMessage", {"prefix": prefix, "command": command, "params": params})

        if command == "RPL_BANLIST":
            channel = params[1]
            mask = params[2]
            owner = params[3]
            time = params[4]

            if channel not in self.banlist.keys():
                done = {"done": False, "total": 1}
                banmask = {"owner": owner.split("!")[0], "ownerhost": owner, "time": time, "mask": mask,
                           "channel": channel}
                done[mask] = banmask
                self.banlist[channel] = done

            else:
                if not self.banlist[channel]["done"]:
                    banmask = {"owner": owner.split("!")[0], "ownerhost": owner, "time": time, "mask": mask,
                               "channel": channel}
                    self.banlist[channel][mask] = banmask
                    self.banlist[channel]["total"] += 1

                else:
                    done = {"done": False, "total": 1}
                    banmask = {"owner": owner.split("!")[0], "ownerhost": owner, "time": time, "mask": mask,
                               "channel": channel}
                    done[mask] = banmask
                    self.banlist[channel] = done

        elif command == "RPL_ENDOFBANLIST":
            channel = params[1]

            if channel in self.banlist.keys():
                self.banlist[channel]["done"] = True
            else:
                self.banlist[channel] = {"done": True, "total": 0}

            self.prnt("|= Got %s bans for %s." % (self.banlist[channel]["total"], channel))

            if self.is_op(channel, self.nickname):
                stuff = self.banlist[channel].keys()
                stuff.remove("done")
                stuff.remove("total")

                for element in stuff:
                    if stuff == "*!*@*":
                        self.send_raw("KICK %s %s :Do not set such ambiguous bans!" % (
                        channel, self.banlist[channel][element]["owner"]))
                        self.send_raw("MODE %s -b *!*@*" % channel)
                        self.send_raw(
                            "MODE %s +b *!*@%s" % (channel, self.banlist[channel][element]["ownerhost"].split("@")[1]))
                    else:
                        self.checkban(channel, element, self.banlist[channel][element]["owner"])

        elif command == "RPL_NAMREPLY":
            me, status, channel, names = params
            users = names.split()
            ranks = "+%@&~"

            if not channel in self.chanlist.keys():
                self.chanlist[channel] = {}

            for element in users:
                rank = ""

                for part in ranks:
                    if part in element:
                        rank = rank + part
                    element = element.strip(part)

                done = { 'server': prefix,
                         'status': rank,
                         'last_time': float( time.time() - 0.25 ) }
                self.chanlist[channel][element] = done

            print "Names for %s%s: %s" % (status, channel, names)

        elif command == "RPL_ENDOFNAMES":
            me, channel, message = params
            ops = 0
            voices = 0
            opers = 0
            aways = 0

            for element in self.chanlist[channel].values():
                status = element["status"]
                if "+" in status:
                    voices += 1
                if "@" in status:
                    ops += 1
                if "*" in status:
                    opers += 1
                if "G" in status:
                    aways += 1
            print("|= %s users on %s (%s voices, %s ops, %s opers, %s away)" % (
            len(self.chanlist[channel]), channel, voices, ops, opers, aways))
            print "[%s] (%s) %s" % (prefix, command, params)

        else:
            print "[%s] (%s) %s" % (prefix, command, params)

これを使用すると、次のエラーが発生します。

  File "C:\Users\Gareth\Documents\GitHub\McBlockit---Helpbot\system\irc.py", line 1422, in irc_unknown
    done = {"server": prefix, "status": rank, "last_time": float(time.time() - 0.25)}
exceptions.UnboundLocalError: local variable 'time' referenced before assignment

ご覧のとおり、ファイルの先頭で時間をインポートしています。そして、そのコードは別の関数で正常に機能します。何か案は?

4

1 に答える 1

7

関数のステートメントでローカル変数がtime定義されています。if

        time = params[4]

ステートメント内にあるため、if何も割り当てられていませんが、その変数のため、インポートされたtimeモジュールは関数で使用できません。

その変数の名前を変更して、競合を解決します。

于 2012-10-20T15:31:56.040 に答える