UnboundLocalError: 局部变量'transaction_id'在赋值前被引用

1 投票
2 回答
567 浏览
提问于 2025-04-19 02:28

我需要一些帮助来找出这个错误。
Python对我来说是个新东西,所以我每天都在努力学习。

class WithdrawHandler(BaseHandler):
def get(self):
    self.redirect(u"/")

@gen.coroutine
def post(self):
    if not self.current_user:
        self.set_status(403, "Forbidden. Please log in first.")
        return

    withdraw_address = json.loads(self.get_argument("withdrawAddress", None))
    username = tornado.escape.json_decode(self.current_user)
    withdraw_amount_str = json.loads(self.get_argument("withdrawAmount", None))
    withdraw_amount = None
    try:
        withdraw_amount = float(withdraw_amount_str)
    except Exception:
        logging.exception("Withdraw Address: " + withdraw_address + " | Username: " + username + " | Withdraw Amount: " + withdraw_amount_str)
        self.set_status(400, "Invalid amount to withdraw.")
        self.finish()
        return

    if not self.coindaemon.validateaddress(withdraw_address).isvalid:
        logging.info("[Invalid Withdraw Address] Withdraw Address: " + withdraw_address + " | Username: " + username + " | Withdraw Amount: " + withdraw_amount_str)
        self.set_status(400, "Invalid withdraw address. Please enter a valid value.")
        self.finish()
        return        

    if float(self.coindaemon.getbalance(username, minconf=2)) < withdraw_amount:
        logging.info("[Insufficient Funds] Withdraw Address: " + withdraw_address + " | Username: " + username + " | Withdraw Amount: " + withdraw_amount_str)
        self.set_status(400, "Insufficient funds to withdraw.")
        self.finish()
        return

    transaction_time = get_sql_datetime()

    try:
        try:
            self.coindaemon.walletpassphrase(options.walletpassword, 60)
        except bitcoinrpc.exceptions.WalletAlreadyUnlocked:
            pass
        transaction_id = self.coindaemon.sendfrom(username, withdraw_address, withdraw_amount, minconf=2, comment="Withdraw")
        query = 'insert into transactions (transaction_id, transaction_type, transaction_time, username, amount, withdraw_address) values (%s, %s, %s, %s, %s, %s);'
        addtransaction = yield momoko.Op(self.db.execute, query, (transaction_id, "withdraw", transaction_time, username, withdraw_amount, withdraw_address))
        balance = self.coindaemon.getbalance(username, minconf=2)
        self.write(dict(bal=str(balance)))
        self.set_status(200)
    except Exception:
        logging.exception("Transaction ID: " + transaction_id + " | Username: " + username + " | Withdraw Address: " + withdraw_address + " | Withdraw Amount: " + withdraw_amount_str + " | Balance: " + str(balance))
        self.set_status(400, "Error withdrawing.")    
    finally:
        self.finish()

当这个错误出现时,它会给我提示。我查了一些资料,发现有关于设置transaction_id为全局变量的说法。这让我感到困惑。

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/tornado/web.py", line 1221, in _when_complete
    if result.result() is not None:
  File "/usr/local/lib/python2.7/dist-packages/tornado/concurrent.py", line 129, in result
    raise_exc_info(self.__exc_info)
  File "/usr/local/lib/python2.7/dist-packages/tornado/gen.py", line 227, in wrapper
    runner.run()
  File "/usr/local/lib/python2.7/dist-packages/tornado/gen.py", line 531, in run
    yielded = self.gen.send(next)
  File "main.py", line 282, in post
    logging.exception("Transaction ID: " + transaction_id + " | Username: " + username + " | Withdraw Address: " + withdraw_address + " | Withdraw Amount: " + withdraw_amount_str + " | Balance: " + str(balance))
UnboundLocalError: local variable 'transaction_id' referenced before assignment

希望有位高手能帮我指点一下方向!

2 个回答

1

看起来

self.coindaemon.walletpassphrase(options.walletpassword, 60)

会引发一个不同于 bitcoinrpc.exceptions.WalletAlreadyUnlocked 的错误,所以里面的 try 语句没能捕捉到这个错误,结果是外面的 try 捕捉到了。因此,在 except Exception 这个部分使用 transaction_id 时,它还没有被设置好。

1

如果 self.coindaemon.sendfrom 出现错误,transaction_id 就不会被设置,这样在处理错误的部分就无法记录这个值。你可以在那行代码之前先给这个变量一个默认值。

撰写回答