You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python类内异步函数调用方法报NameError 无法访问变量问题

问题说明

编写Connect类实现币安WebSocket异步获取BTCUSDT交易价格逻辑时,运行代码触发报错:在main异步函数中调用Get2(data_price)时抛出NameError,提示名称'Get2'未定义,同时异步函数内的data_price变量无法正常向外传递。

原始问题代码
class Connect():
    global data_price
    async def main():
       
        client = await AsyncClient.create()
        bm = BinanceSocketManager(client)
        # start any sockets here, i.e a trade socket
        ts = bm.trade_socket('BTCUSDT')
        # then start receiving messages
        async with ts as tscm:
                res = await tscm.recv()
                data_price = res['p']
                print(data_price)
                data_time = datetime.datetime.now()
                data_time = datetime.datetime.now()
                c.execute('''INSERT INTO data VALUES(?,?)''', (data_time, data_price))
                connect_db.commit()
                c.execute('''SELECT * FROM data''')
                data_display = c.fetchall()
                print(data_price)
                Get2(data_price)
                
                
        await client.close_connection()

    if __name__ == "__main__":
        loop = asyncio.get_event_loop()
        loop.run_until_complete(main())
      
    def Get2(data_price):
        print(data_price)
报错栈信息
Traceback (most recent call last):
  File "C:\Users\Rhyan\Desktop\Py project\crytpo.py", line 30, in <module>
    class Connect():
  File "C:\Users\Rhyan\Desktop\Py project\crytpo.py", line 57, in Connect
    loop.run_until_complete(main())
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\asyncio\base_events.py", line 647, in run_until_complete
    return future.result()
  File "C:\Users\Rhyan\Desktop\Py project\crytpo.py", line 50, in main
    Get2(data_price)
NameError: name 'Get2' is not defined
报错核心原因
  • 你把程序入口if __name__ == "__main__"的执行逻辑直接写在了Connect类的定义块内部,这部分代码会在类加载定义阶段立刻执行,此时Connect类还没完成定义,内部的Get2方法还没完成注册,自然找不到对应名称。
  • 类内部定义的普通方法属于类的命名空间,不能像全局函数一样直接裸调用,必须通过类实例引用访问。你在main里直接写Get2(),Python只会去全局作用域找这个函数,当然匹配不到类内部定义的Get2方法。
  • 类的实例方法第一个参数必须传入代表实例本身的self参数,你写的main、Get2方法都没加这个参数,就算解决了名称找不到的问题,调用时也会触发参数数量不匹配的报错。
  • 你在类开头写的global data_price写法无效:global关键字只能用来声明函数内的变量来自全局作用域,放在类的代码块第一行没有任何作用。类内跨方法传递变量应该用实例属性,不要滥用全局变量。
修复后可运行代码
import asyncio
import datetime
import sqlite3
from binance import AsyncClient, BinanceSocketManager

class Connect:
    def __init__(self):
        # 初始化数据库连接,作为实例属性供类内方法共享
        self.connect_db = sqlite3.connect('crypto_price.db')
        self.c = self.connect_db.cursor()
        self.c.execute('''CREATE TABLE IF NOT EXISTS data (collect_time datetime, btc_price real)''')
        self.connect_db.commit()
        self.data_price = None

    async def main(self):
        client = await AsyncClient.create()
        bm = BinanceSocketManager(client)
        ts = bm.trade_socket('BTCUSDT')
        async with ts as tscm:
            res = await tscm.recv()
            self.data_price = float(res['p'])
            print(f"实时获取价格: {self.data_price}")
            data_time = datetime.datetime.now()
            self.c.execute('''INSERT INTO data VALUES(?,?)''', (data_time, self.data_price))
            self.connect_db.commit()
            self.c.execute('''SELECT * FROM data''')
            data_display = self.c.fetchall()
            print(f"数据库存储记录: {data_display}")
            # 类内部调用自身方法需要通过self引用
            self.Get2(self.data_price)
        await client.close_connection()
        self.connect_db.close()

    def Get2(self, data_price):
        print(f"Get2方法接收到价格参数: {data_price}")

if __name__ == "__main__":
    # 类定义完成后再实例化、启动事件循环
    conn_instance = Connect()
    loop = asyncio.get_event_loop()
    loop.run_until_complete(conn_instance.main())
修复要点
  • 把if __name__ == "__main__"入口逻辑移到类定义外部,等类完全加载完成后再实例化调用
  • 所有实例方法添加self作为第一个参数,类内部的属性、方法调用统一通过self.xxx的形式访问
  • 类内需要跨方法传递的变量(比如价格、数据库连接对象)统一存为实例属性,不要滥用global全局变量
  • 数据库连接、WebSocket连接使用完成后显式关闭,避免资源泄漏

内容的提问来源于stack exchange,提问作者Ryan morris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 08:48:31