首页/新闻资讯/正文详情

Python *args 与 **kwargs:定义收集、调用解包与参数透传详解

发布时间:2026/11/4 5:20:13 来源:云帆数科 栏目:资讯中心
Python *args 与 **kwargs:定义收集、调用解包与参数透传详解
1. 从一次 TypeError 说起* 和 ** 在参数里到底扮演什么角色我第一次被这两个星号绊住是接手一段别人留下的日志封装代码。调用方按文档传了三个位置参数加一个retry3结果运行到一半直接抛TypeError: log_event() got an unexpected keyword argument retry。翻到函数定义那一行才发现写的是def log_event(message, *args, **kwargs)看起来什么都收但真正的配置项被写进了**kwargs里后面某处又用kwargs[retry]硬取键名拼错成了retires于是一路带着None往下跑直到某个分支才炸。这件事之后我才认真把*和**的两种身份拆开来看——它们在 Python 里其实是两套完全不同的机制只是共用了同一个符号。一句话概括在函数定义的位置上*args负责把多出来的位置参数打包成一个元组**kwargs负责把多出来的关键字参数打包成一个字典在函数调用的位置上*负责把一个可迭代对象摊开成若干个位置实参**负责把一个映射摊开成若干个关键字实参。定义端是收调用端是放方向正好相反。很多人写代码时把两者混着理解写出来的签名看着能用实际一传参就出问题。1.1 报错信息里的两条线索Python 在这件事上的报错其实很诚实只是平时没人细读。takes 2 positional arguments but 3 were given说的是位置参数数量对不上说明函数没有开*args这个口子got an unexpected keyword argument说的是关键字参数没被任何形参接住说明既没有同名形参也没有**kwargs兜底got multiple values for argument则是同一个形参被位置和关键字各喂了一次。这三类错误基本覆盖了新手 90% 的传参翻车场景而它们的解法都指向同一件事搞清楚当前函数签名到底允许哪些参数、以什么形式进来。我后来养成了一个习惯遇到这类报错先不看函数体直接print(inspect.signature(目标函数))把签名打出来对着看。签名是(a, b1, *args, c, **kwargs)还是(a, b1)决定了调用方能用什么姿势传参比读十行函数体都快。这个方法在接手陌生代码库时尤其管用尤其是那些被装饰器层层包裹过的函数露出来的签名和真实签名经常不是一回事。1.2 定义端收集与调用端铺开的分工把两种角色分开记很多疑惑会瞬间消失。定义端的星号是声明式的它写在def里告诉解释器如果有多余的参数别报错按这个规则收起来调用端的星号是表达式式的它写在函数名后面的括号里告诉解释器把这个容器里的元素逐个拿出来当实参。前者决定了函数能接受什么后者决定了这次调用给什么。一个容易被忽略的细节是调用端的*和**并不是只能配合*args/**kwargs使用。哪怕目标函数是def add(a, b):这种最普通的签名你依然可以写add(*(1, 2))或者add(**{a: 1, b: 2})效果和add(1, 2)完全一样。星号属于调用语法本身跟被调函数长什么样没有绑定关系。反过来说定义了*args的函数也可以被普通方式调用此时args就是个空元组而已。理解这层分工之后我再看那些万能转发的代码就顺畅多了外层def wrapper(*args, **kwargs)把收到的东西原样收起来内层func(*args, **kwargs)再原样摊开送出去中间不做任何解释。这套动作的本质就是我不知道你传什么所以我不碰原样搬。装饰器、代理层、事件总线、插件调度几乎所有需要透传参数的场景都是这个套路。2. 定义端的 *args多余位置参数被装进元组先看最基础的一段代码def collect(first, *rest): print(first, type(rest), rest) collect(1) collect(1, 2, 3) collect(1, a, None, [4])输出依次是1 class tuple ()、1 class tuple (2, 3)、1 class tuple (a, None, [4])。这里有个关键点值得强调rest拿到的是tuple不是 list。很多从其他语言转过来的人会下意识以为它是个可变序列写rest.append(x)然后报AttributeError。Python 选 tuple 是有道理的——参数在函数调用那一刻就确定了之后不应该被改动用不可变类型天然防止了函数内部偷偷修改参数集合。2.1 它拿到的是 tuple不是 list这个细节在实际项目里影响不小。如果你确实需要在函数内部对收集到的参数做增删正确做法是先list(rest)转一下或者干脆写items list(rest)再操作。直接把rest当 list 用在测试环境可能碰巧不报错因为测试用例只传了一个参数rest是空元组某些操作在空元组上恰好不触发上了生产才炸这种 bug 排查起来非常费劲。另一个相关的问题是*args收集到的参数可以是任意对象包括生成器、迭代器、函数、类本身。这意味着你不能假设args里的元素类型统一除非你自己在函数开头做校验。我之前写过一个批量处理工具签名是def process(*tasks)结果有调用方传了一个列表进来整个列表被当成单个元素塞进了tasks函数内部还按每个元素是一个任务去遍历最后处理了一个 list 对象。修法是在文档里写清楚每个任务单独作为位置参数传入或者老老实实改成def process(tasks)接收一个列表把是否摊开的决定权交给调用方。2.2 *args 后面的普通参数去哪了这是新手最容易迷惑的地方。写下def f(a, *args, b):时b到底是什么答案是b变成了仅限关键字参数只能通过f(1, 2, 3, b4)这种形式传写成f(1, 2, 3, 4)会报错说b缺失。原因很直观——*args已经把后面所有的位置参数都吃掉了再想在它后面声明一个普通位置参数在语法上是矛盾的所以 Python 干脆把*args之后的所有形参都划归为关键字专属。这个规则有个非常实用的推论如果你在参数列表里写了*args那么它后面的所有参数都必须靠关键字传。反过来说如果某个参数你希望调用方一定要写参数名可以故意用*args或者单独一个*把它挡到后面去详见第 4 节。这是 Python 里表达这个参数必须显式命名的标准手法比在文档里加粗提醒可靠得多。还有一个更隐蔽的坑*args之后不能再接带默认值的位置参数因为语法上已经不允许了。有人试图写def f(*args, b1)期望b是可选位置参数实际b是可选关键字参数f(1, 2)里 1 和 2 全进argsb仍是 1。这个差异导致函数行为跟预期完全不同而代码本身不报错属于典型的能跑但不对。2.3 名字叫 args 只是约定星号才是关键args和kwargs这两个名字纯粹是社区约定你完全可以写成def f(*items, **options)功能一模一样。约定俗成的好处是看签名就知道是可变参数坏处是有时候会让人误以为名字有特殊含义。我见过有人写def f(*kwargs)试图收集关键字参数结果拿到的是一个元组也有人写def f(**args)然后惊讶于取出来的东西是字典而不是元组。名字骗人星号从不骗人。更麻烦的是有些库为了可读性用了自定义名字比如def execute(*statements, **context)初看以为是业务参数其实是可变参收集器。读这类代码时一定要盯着星号在谁前面不要被名字带跑。我的做法是在 review 代码时凡是看到*或**开头的形参一律把它当作兜底容器处理绝不在没有校验的情况下假设它的形状和元素类型。顺带说一句命名风格的取舍。*args这种通用名字适合底层工具函数、装饰器、转发层因为它们确实不关心具体内容而业务函数如果用*args最好换成有语义的名字比如*extra_filters、*fallback_paths让调用方一眼看出该往里塞什么。这条经验来自一次团队协作——一个函数签名是def query(*conditions)结果有人传了列名有人传了 SQL 片段有人传了字典最后炸成一锅粥改名的沟通成本远低于事后排查的成本。3. 定义端的 **kwargs关键字参数被收进字典**kwargs的行为对称但细节不同。看这段def configure(name, **options): print(name, type(options), options) configure(cache) configure(cache, size128, ttl60)输出是cache class dict {}和cache class dict {size: 128, ttl: 60}。和*args拿到 tuple 不同这里拿到的是标准的 dict可以正常增删改查。这个差异是有意设计的——关键字参数天生就是名字到值的映射用 dict 承载最自然。3.1 键必须是字符串这条隐含约束**kwargs里面装的键必须是字符串这是 Python 语言层面的硬性要求不是约定。如果你尝试f(**{1: a})会直接报TypeError: keywords must be strings。这条约束在正常传参时几乎不会被察觉因为f(a1)写法本身就限定了键是标识符但一旦引入动态构造的字典问题就冒出来了。我遇到过真实场景一个任务调度器需要把配置字典透传给下游函数配置是从配置文件如 YAML/TOML读出来的理论上键都是字符串。但有一处合并逻辑用了dict.update(list_of_pairs)其中某对数据的键被序列化成了整数整条链路一直是能跑的直到某次下游函数签名变更导致这个字典被**展开才突然报错。这类问题的排查成本极高因为出错点和错误源头隔着好几层调用。我的经验是任何准备被**展开的字典在构造边界处就做一次键类型断言代价几乎为零收益是把问题挡在源头。3.2 显式参数与 **kwargs 的抢夺战当函数同时有显式关键字参数和**kwargs时Python 的分配规则是先给显式参数剩下的再进kwargs。也就是说def f(a, b2, **kwargs): print(a, b, kwargs) f(1, b3, c4) # 1 3 {c: 4} f(1, c4) # 1 2 {c: 4}但如果同一个参数既通过位置、又通过显式关键字给了就会触发got multiple values错误f(1, 2, b3) # TypeError这里有个容易踩的边界如果显式参数是通过**字典传进去的会怎样答案是同样会触发冲突def g(a, b2): pass g(1, **{b: 3}) # 正常1 3 g(1, **{a: 2}) # TypeError: got multiple values for argument a第二种写法的行为常常让人意外因为从字面上看g(1, **{a: 2})像是补一个 a但 Python 认为位置参数已经把a占了字典里的a是重复赋值。我在写配置合并工具时被这个坑过用户传参是位置参数 覆盖字典覆盖字典里如果恰好包含第一个位置参数的名字就得先把它 pop 掉再展开。这个处理逻辑后来被我写成了一个通用的merge_kwargs小函数专门负责剔除冲突键。4. 单独一个 * 和单独一个 /两种禁区标记除了成对出现的*args和**kwargsPython 还允许在参数列表里单独写一个星号或者单独写一个斜杠。这两个符号不带名字作用是给参数划分传参方式禁区。它们的设计动机是让 API 的作者能精确控制调用方必须怎么写而不是依赖文档提醒。4.1 光秃秃的 * 是仅限关键字参数的分界线def crop(image, *, width, height, keep_ratioTrue): ... crop(img, width100, height80) # 合法 crop(img, 100, 80) # TypeError单独一个*之后的参数全部只能通过关键字传。这个特性在库设计里非常有用因为位置参数一旦超过两三个调用方就很难记住顺序。crop(image, 100, 80)到底是先宽后高还是先高后宽没人记得住。强制写成关键字之后代码的可读性会显著提升而且后续调整参数顺序也不会破坏调用方。值得一提的是单独的*和*args在划分关键字禁区这件事上效果是一样的。def f(a, *args, b)里的b也是仅限关键字。区别在于*args还额外接收多余的位置参数单独*则直接拒绝多余的位置参数。所以如果你的函数不需要收集可变位置参数只是想让后面的参数必须写名字用单独*语义更准确签名也更干净。4.2 / 标记的仅限位置参数Python 3.8 之后和*对称的是/它出现在参数列表里标记它前面的参数只能按位置传不能按关键字传def load(path, /, moder): ... load(a.txt) # 合法 load(a.txt, moderb) # 合法 load(patha.txt) # TypeError这个特性是从 C 实现的内置函数如len、range那里反向借鉴来的——那些函数的参数名对用户不可见传关键字会失败。Python 3.8 之前用户自己写的纯 Python 函数无法复现这个行为3.8 之后用/就可以了。实际项目里/用得比*少但在一些场景下很有价值。比如你想保留参数名改动的自由def scale(x, y, /, factor2)里x和y的名字可以改只要位置不变对调用方毫无影响而factor是关键字参数名字一改就是破坏性变更。如果是写一个对性能敏感、调用极频繁的底层函数位置参数传递也略快一点点少了关键字匹配的开销虽然这点差异在 Python 里通常可以忽略。4.3 一条完整的参数排序规则把/、普通参数、*、*args、**kwargs全放一起规则就定死了位置参数类型示例传参方式最前仅限位置参数a, b在/之前只能位置中间普通参数c, d1在/之后、*之前位置或关键字之后可变位置参数或分隔符*args或*收集位置或禁止位置再后仅限关键字参数e, f2只能关键字最后可变关键字参数**kwargs收集关键字完整示例如下def full(a, b, /, c, d1, *args, e, f2, **kwargs): pass这个签名虽然看着复杂但只要你按表格从上往下读每一段允许什么传法就一目了然。我在给团队做代码规范时把这张表印成了 A4 贴在工位上因为参数顺序写错导致的语法错误非常费时间——解释器只会告诉你 positional argument follows keyword argument不会告诉你具体该怎么排。5. 调用端的解包把一个容器摊开成多个实参前面说的都是定义端现在换个视角。调用端的星号解决的是我手里有个容器但函数要的是一串参数这个问题。def add(a, b, c): return a b c values [1, 2, 3] print(add(*values)) # 6 options {a: 1, b: 2, c: 3} print(add(**options)) # 6这段代码在心智上要理解成values被拆成了三个独立实参传进去而不是values作为一个列表传进去。区别在于add(values)会让a拿到整个列表然后b、c缺失报错add(*values)则让a1, b2, c3。5.1 * 解包可迭代对象** 解包映射*后面跟的可以是任何可迭代对象list、tuple、set、字符串、生成器、range、自定义实现了__iter__的对象。这带来一些有趣但危险的行为add(*abc) # ValueError: 参数数量对不上因为 abc 拆成 a,b,c add(*range(3)) # 6 add(*{1, 2, 3}) # 6但顺序不确定字符串被拆成字符、集合被拆成无序元素这两点经常让新手困惑。如果字符串正好是三字符add(*abc)会以aa, bb, cc的形式成功执行然后返回abc看起来没报错但结果完全不是预期的数值相加。所以解包字符串基本属于要避免的写法真需要拆字符请显式写list(s)或者tuple(s)让意图更明确。**后面跟的必须是映射类型实现了keys()和__getitem__的对象最常见的是 dict也可以是collections.ChainMap之类的映射实现。普通的 list 或 tuple 放在**后面会直接报错。这个限制其实很合理——关键字参数必须有名字列表没有名字。5.2 重复赋值引发的 TypeError 从哪来解包时最常见的报错是got multiple values for argument根源在于位置和关键字两条通道同时给同一个形参赋值了def send(to, subject, body): pass params {to: x, subject: y, body: z} send(x, **params) # TypeErrorto 被赋了两次修法有两种要么去掉多余的位置参数要么在展开前把字典里冲突的键删掉params.pop(to) send(x, **params)另一个常见来源是多个字典合并展开send(**d1, **d2)Python 3.5 之后支持这种写法规则是后出现的覆盖先出现的但如果同一个键在两个字典里都有、且目标函数没有对应形参能接住也就是进**kwargs时那么后一个会覆盖前一个不报错。然而如果目标函数有具名形参重复键就会触发上面那个错误。这个行为差异容易让人误判我的做法是合并字典时显式用{**d1, **d2}先构造好再展开逻辑更清楚也能提前发现覆盖问题。5.3 生成器只能被消费一次的解包陷阱*解包会完整遍历可迭代对象这意味着生成器在解包之后就被耗尽了def total(*nums): return sum(nums) gen (x for x in range(5)) print(total(*gen)) # 10 print(total(*gen)) # 0gen 已空如果这个生成器本来要用于两处第二处就会拿到空结果而且不报错。这类 bug 特别隐蔽因为程序照常运行只是数据悄悄变少了。我的应对策略是凡是要被*展开的迭代对象如果不是 list/tuple 这类确知可重复遍历的类型先list()一下明确表示这是要落地的数据。多一次物化换一份确定性在绝大多数业务场景里是划算的。6. 装饰器与转发这对组合真正值钱的地方前面都是零件现在看主战场。*args和**kwargs被使用频率最高的地方是各种需要参数透传的场景其中最典型的就是装饰器。6.1 通用包装器的签名透传import functools def retry(times3): def decorator(func): functools.wraps(func) def wrapper(*args, **kwargs): last_error None for attempt in range(times): try: return func(*args, **kwargs) except (ValueError, TimeoutError) as exc: last_error exc raise last_error return wrapper return decorator retry(times2) def fetch(url, timeout5): ...这里的wrapper(*args, **kwargs)是关键装饰器本身不知道被装饰函数长什么样也不知道调用方会传什么所以只能原封不动地收下来、再原封不动地送出去。如果写成def wrapper(url, timeout5)那这个装饰器就只能用于fetch这种签名的函数换一个函数就得重写。通用性正是靠这两个星号换来的。这也解释了为什么装饰器代码里几乎看不到显式参数名。显式写出参数名意味着你要跟被装饰函数的签名耦合而成熟的装饰器库日志、缓存、限流、重试都追求与业务函数解耦。*args和**kwargs是唯一能做到不关心具体签名的语法手段。6.2 functools.wraps 保住的到底是什么严格说functools.wraps不是*/**相关但去掉它会立刻产生连锁反应。不加functools.wraps(func)时wrapper.__name__是wrapperwrapper.__doc__是Nonewrapper.__module__也丢了。更实际的影响是inspect.signature(wrapper)返回的是(*args, **kwargs)而不是原函数的签名。这意味着基于签名做校验的框架会失效。比如某个参数校验中间件会读取目标函数的签名来判断必填项装饰器一包签名就从(url, timeout5)变成了(*args, **kwargs)校验逻辑直接失效所有参数都变成可选的错误就漏到了运行时。我遇到过一次参数校验完全失灵的事故排查了很久才发现是某个新加的装饰器忘了写functools.wraps。加了之后inspect.signature能通过__wrapped__属性追溯到原函数拿到真实签名。需要注意的是__wrapped__只是一个属性不是魔法它的作用是让标准库的inspect模块在解析签名时自动跟随。如果你用了一些自研的反射工具很可能没处理这个字段那就得自己读__wrapped__。6.3 类型标注写在 *args 和 **kwargs 上的含义Python 3.5 之后可以给它们加类型标注但语义要理解准确def f(*args: int, **kwargs: str) - None: ...*args: int表示每一个位置参数都是intargs本身的类型是tuple[int, ...]**kwargs: str表示每一个关键字参数的值都是strkwargs本身的类型是dict[str, str]。写成*args: tuple[int, ...]是错的那表示每个位置参数都是一个元组。这个细节在使用mypy或pyright做静态检查时会被严格校验。我见过把注解写成**kwargs: dict的代码静态检查器会要求每个关键字参数的值都是 dict传一个timeout5就报错。正确写法是**kwargs: Any如果不关心值类型或者用Unpack[TypedDict]如果需要精确描述键集合Python 3.11 之后配合typing_extensions可用。7. 几个我踩过的坑和取舍建议7.1 可变默认值与 *args 的混淆这两个知识点经常被放在一起讲但它们是不同的问题。可变默认值指的是def f(items[])这种写法默认列表在函数定义时创建一次、被所有调用共享而*args是每次调用新建一个元组不存在共享问题。混淆它们会导致奇怪的结论比如用*args代替默认参数——这不是一个可选项因为语义完全不同*args是可变数量的位置参数默认参数是单个可选参数。真正需要防的是可变默认值那个坑def append_tag(tag, tags[]): tags.append(tag) return tags连续调用两次会得到累加的结果。标准修法是tagsNone然后在函数内初始化def append_tag(tag, tagsNone): tags [] if tags is None else tags tags.append(tag) return tags这个问题和*args的唯一联系是两者都发生在参数列表里都容易被顺手写错。分开记别混着记。7.2 滥用 **kwargs 让函数签名失去可读性**kwargs好用但它是可读性的天敌。一个函数如果写成def handle(event, **kwargs)调用方完全不知道能传什么、该传什么只能翻文档或者读源码。我在维护一个内部 SDK 时深受其害——早期为了向后兼容把所有新增参数都塞进**kwargs两年后函数签名变成def process(payload, **kwargs)文档里列了 27 个可选键没有一个 IDE 能提示出来每次接新需求都要翻半天。后来的改法是能具名的参数一律具名只在确实需要透传给下游、且内容完全由调用方决定的场景才保留**kwargs。比如def request(url, *, methodGET, headersNone, **extra)前几个参数是核心配置必须能自动补全和类型检查extra是给特殊场景留的口子接受传了就有、不传就没的灵活性。这个划分标准我认为可以推广签名里出现**kwargs时问自己一句这些键名我能不能列举出来能列举就具名列举不出来才用**。7.3 关于性能的一点点实测感受经常有人问*args和**kwargs会不会慢。我做过粗略对比一个空的def f(a, b): pass和def f(*args, **kwargs): pass后者在调用时需要打包 tuple 和 dict单次开销确实高一些量级在几十纳秒。这个差异在业务代码里完全可以忽略因为一次网络请求是毫秒级、一次数据库查询是几十毫秒级参数打包的开销连零头都不算。真正需要在意的是热点路径上的极端情况比如一个被调用上百万次的数值计算函数。那种场景下确实应该用显式参数但理由是可读性 可被 C 层优化而不是星号慢。我个人的判断是普通业务代码按可读性优先选参数形式性能敏感代码按 profile 结果决定不要凭感觉预优化。见过太多为了躲一个根本不存在的性能问题把函数签名搞得极其难用的代码得不偿失。最后分享一个小技巧用来快速检查一个函数的真实签名和解包情况import inspect def probe(func, *args, **kwargs): print(inspect.signature(func)) bound inspect.signature(func).bind(*args, **kwargs) print(bound.arguments) probe(some_function, 1, 2, modefast)bind会按真实签名分配参数不执行函数体能在调用前就把参数错误暴露出来。这个方法在写测试用例或者做参数调试时非常好用比反复触发TypeError再回头改代码高效得多。

相关推荐

Meta Muse 架构深度拆解:从 Agent Runtime 到安全虚拟机,构建生产级 AI Agent
Meta Muse 架构深度拆解:从 Agent Runtime 到安全虚拟机,构建生产级 AI Agent

1. 从“对话”到“执行”:Meta Muse 到底改变了什么第一次看到 Meta Muse 这个架构的时候,我脑子里冒出来的第一个念头不是“又一个 Agent 框架”,而是——它把过去两年我们对 AI 的用法整个翻了个面。过去我们和模型打交道,本质上… · 2026/11/4 5:20:13

TurboQuant:在线向量量化技术的突破与实践
TurboQuant:在线向量量化技术的突破与实践

1. 项目概述:在线向量量化的突破性方案TurboQuant 是一种革命性的在线向量量化技术,能够在数据流持续输入的场景下,实时构建量化码本并保持接近理论最优的失真率。这项技术解决了传统量化方法在动态数据环境中的三大痛点:码本更新… · 2026/11/4 5:20:13

Meta Muse 架构解析:AI Agent 运行时与安全虚拟机设计
Meta Muse 架构解析:AI Agent 运行时与安全虚拟机设计

1. 从“回答问题”到“替你做事”:Meta Muse 到底在解决什么问题第一次看到 Meta Muse 这个架构名,是在一个做企业级 AI 应用的朋友群里。当时有人甩了张截图,说“Meta 这次不是发模型,是发了一套让模型真正干活的运行时”。这句话… · 2026/11/4 5:20:13

OpenClaw全栈AI开发环境一键部署指南
OpenClaw全栈AI开发环境一键部署指南

1. 项目概述:OpenClaw开发环境全栈解决方案OpenClaw作为当前AI开发领域的热门工具链,其部署过程往往成为新手入门的第一个障碍。我在实际团队协作中发现,超过60%的开发者卡在环境配置阶段,特别是CUDA驱动版本冲突、Python虚拟环境… · 2026/11/4 7:40:36

机器人逆向运动学原理与应用解析
机器人逆向运动学原理与应用解析

1. 逆向运动学基础概念在机器人控制领域,逆向运动学(Inverse Kinematics, IK)是指根据末端执行器的期望位姿,求解机器人各关节角度的过程。这与正向运动学(Forward Kinematics)形成鲜明对比——正向运动学是… · 2026/11/4 7:40:36

高斯数据库性能优化全攻略:从架构到SQL实战
高斯数据库性能优化全攻略:从架构到SQL实战

1. 高斯数据库性能优化概述高斯数据库作为企业级关系型数据库的代表,其性能表现直接影响着业务系统的响应速度和吞吐量。在实际生产环境中,我们经常会遇到查询缓慢、连接池耗尽、索引失效等典型性能问题。这些问题往往不是单一因素造成的,而是… · 2026/11/4 7:40:36

自动驾驶技术栈全解析:从感知到控制的系统设计
自动驾驶技术栈全解析:从感知到控制的系统设计

1. 自动驾驶技术全景概览第一次接触自动驾驶系统时,最让我震撼的是这个看似简单的"开车"动作背后竟包含着如此复杂的技术体系。现代自动驾驶系统就像一位经验丰富的老司机,需要同时具备敏锐的感官(感知)、快速的大脑&am… · 2026/11/4 7:40:36

擎控机器人获七项国际标准管理体系认证,加速布局具身智能跨境数据服务
擎控机器人获七项国际标准管理体系认证,加速布局具身智能跨境数据服务

2026年9月,擎控机器人取得七项国际标准管理体系认证,并获评AAA级信用企业。此次获证,覆盖数字化数据处理业务的质量、服务、安全与隐私等关键管理领域,为公司拓展具身智能跨境数据服务、深化国际业务合作增添了新的支撑。七项认证… · 2026/11/4 7:40:36

Milvus向量数据库实战:从部署到性能优化
Milvus向量数据库实战:从部署到性能优化

1. 为什么需要向量数据库?在信息爆炸的时代,非结构化数据(如图片、视频、音频、文本)的处理成为技术难点。传统关系型数据库擅长处理结构化数据,但对非结构化数据的相似性搜索无能为力。这就是向量数据库的用武之地——… · 2026/11/4 7:39:36

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 6:59:29

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 7:02:38

AI辅助技术栈评估:提升研发决策效率60%
AI辅助技术栈评估:提升研发决策效率60%

1. 项目背景与核心价值技术决策一直是研发团队面临的重大挑战。随着技术生态的快速演进,技术栈的选择、维护和迭代变得愈发复杂。我们团队在过去两年里,先后经历了三次重大技术栈迁移,每次都需要投入大量人力进行技术评估和风险分析。直到去年… · 2026/11/4 0:00:17

从生成Token到直接决策:Jev如何重塑AI Agent工程实践
从生成Token到直接决策:Jev如何重塑AI Agent工程实践

1. 从"生成文字"到"拍板决策":Jev 到底在解决什么问题大多数人第一次接触大模型,脑子里建立的模型是"输入问题、输出文字"。你问它今天天气怎么样,它给你一段描述;你让它写个周报,它给你… · 2026/11/4 0:00:17

32G统一内存跑大模型:内存账、TPS实测与端云分流
32G统一内存跑大模型:内存账、TPS实测与端云分流

想在一台 32G 统一内存的小主机上把大模型跑成"日常可用",这件事我前后折腾了小半年。标题里说的这台 Mac mini M6,是我们这次讨论的目标平台,具体到手规格以实物为准;但下面这套推算方法和实测思路,对任何统… · 2026/11/4 0:00:17

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 6:59:29

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 7:02:38

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码