
aiogram 3.x 已弃用 BoundFilter,推荐通过继承 aiogram.filters.Filter 创建异步可调用过滤器,或直接使用 Magic Filter(如 F.text.isalnum()),但需注意其对 Unicode 字符的宽松行为。
aiogram 3.x 已弃用 boundfilter,推荐通过继承 `aiogram.filters.filter` 创建异步可调用过滤器,或直接使用 magic filter(如 `f.text.isalnum()`),但需注意其对 unicode 字符的宽松行为。
在 aiogram 3.x(如 3.4+)中,BoundFilter 已被彻底移除,不再存在于任何模块路径中(aiogram.filters、aiogram.dispatcher.filters 等均无该类)。取而代之的是统一、更灵活的过滤器模型:所有自定义过滤器必须继承 aiogram.filters.Filter,并实现异步 __call__ 方法,返回 bool 值。
✅ 推荐方案一:使用 Magic Filter(简洁场景)
若只需基础校验(如仅允许 ASCII 字母+数字),可优先尝试 Magic Filter:
from aiogram import F
from aiogram.types import Message
@dp.message(F.text.regexp(r'^[a-zA-Z0-9]*$')) # 精确匹配纯英文+数字(不含空格/符号/Unicode)
async def handle_alnum_only(message: Message):
await message.answer(f"Valid input: {message.text}")⚠️ 注意:F.text.isalnum() 不满足严格 ASCII 要求——它会接受 ą, ść, 中文, 日本語 等 Unicode 字母/数字,等价于 Python 的 str.isalnum(),因此不能替代原问题中的白名单逻辑。
✅ 推荐方案二:自定义 Filter 类(精准控制)
当需要精确限定字符集(如仅 a–z, A–Z, 0–9),应继承 aiogram.filters.Filter:
from aiogram.filters import Filter
from aiogram.types import Message
class AllowedAsciiAlnumFilter(Filter):
def __init__(self) -> None:
# 显式定义 ASCII 字母+数字集合(不含 Unicode)
self.allowed_chars = frozenset(
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
)
async def __call__(self, message: Message) -> bool:
text = message.text
# 空消息或非文本类型直接拒绝
if not isinstance(text, str) or not text:
return False
# 逐字符检查是否全在白名单内
return all(char in self.allowed_chars for char in text)
# 在路由中使用
@dp.message(AllowedAsciiAlnumFilter())
async def handle_clean_input(message: Message):
await message.answer(f"✅ Accepted: '{message.text}'")? 关键要点:
- ✅ Filter 是唯一官方支持的基类,必须实现 async __call__(self, event) -> bool;
- ✅ 使用 frozenset 提升字符查找性能(O(1));
- ✅ 显式处理 None 或非字符串 message.text(如语音转文字失败、纯表情消息);
- ✅ 过滤器实例可复用(无需每次 MyFilter() 新建),建议定义为全局常量以优化性能;
- ❌ 不要尝试导入 BoundFilter——它在 3.x 中已不存在,强行导入将引发 ImportError。
? 完整可运行示例(含测试)
from aiogram import Bot, Dispatcher, F
from aiogram.filters import CommandStart, Filter
from aiogram.types import Message
# 自定义过滤器(复用优化版)
ASCII_ALNUM_FILTER = AllowedAsciiAlnumFilter()
@dp.message(CommandStart())
async def start_handler(message: Message):
await message.answer("Send alphanumeric ASCII text only!")
@dp.message(ASCII_ALNUM_FILTER)
async def echo_handler(message: Message):
await message.answer(f"Echo: `{message.text}`")
@dp.message() # 捕获所有未匹配消息(用于提示)
async def fallback_handler(message: Message):
await message.answer("❌ Only English letters and digits allowed (e.g., 'Hello123').")? 最佳实践总结:
- 优先用 Magic Filter 快速验证(如 F.text.regexp(...));
- 复杂逻辑或需复用时,封装为 Filter 子类;
- 避免在 __call__ 中执行耗时 I/O(如数据库查询),必要时改用中间件;
- 所有过滤器必须是异步可调用对象,同步函数无法被 aiogram 3.x 正确识别。

















