在Python项目中,我们经常会看到类似这样的代码:
|
|
很多初学者会疑惑:
__all__是做什么的?- 为什么需要它?
- 和
_xxx命名有什么区别? - 大型项目为什么经常使用?
本文将从基础语法到工程实践,深入理解 Python 的__all__。
在Python项目中,我们经常会看到类似这样的代码:
|
|
很多初学者会疑惑:
__all__是做什么的?_xxx命名有什么区别?本文将从基础语法到工程实践,深入理解 Python 的__all__。
在工业自动化设备开发过程中,机器视觉往往是决定设备精度和稳定性的关键环节。很多时候,我们面对一个视觉检测需求,第一反应可能是:“有没有一个现成的算子可以解决?”。边缘检测、模板匹配、Blob分析……这些算法在 Halcon、OpenCV 等视觉库中已经被封装得非常方便。但随着项目复杂度提升,真正困难的问题逐渐浮现:
这些问题本质上不是“会不会调用算子”,而是是否建立了完整的机器视觉算法体系。
《机器视觉算法与应用(第2版)》由 Carsten Steger(MVTec 联合创始人) 等人编写,是工业机器视觉领域非常经典的一本参考书。它没有简单罗列各种视觉算法,而是从图像形成、特征提取、定位、测量、识别等角度,系统介绍机器视觉中常见问题背后的数学原理和工程方法,这篇文章记录阅读过程中的一些理解和总结,希望通过这个过程,把零散的视觉知识,逐步整理成一套可以用于实际设备开发的“认知框架”。。
作为此前专注于软件/算法开发、并逐步向工业设备与机电一体化方向延伸的工程师,这本书给我的冲击更多来自“视角切换”——从纯软件系统的抽象世界,进入到机械、电气与控制交织的真实物理系统之中。过去在写代码时,我们习惯处理的是确定性的输入输出:接口、协议、状态机、数据流,一切都可以在逻辑层面闭环。但在机电一体化系统中,变量开始变得“有重量”:惯性、摩擦、延迟、抖动、误差累积,这些因素不再是边界条件,而是系统设计的一部分。软件不再只是“控制逻辑”,而是与硬件共同构成一个持续运行的闭环系统。
这本书的价值,并不只是讲解机械结构或电气控制原理,而是在不断强调一个核心思想:真正的机电一体化,不是“机械 + 电气 + 软件”的简单叠加,而是三者在设计阶段就必须协同优化的系统工程。
对我而言,这种思维方式的转变尤为重要。因为在实际设备开发中,很多问题并不是“代码 bug”,而是系统层面的设计耦合问题:
这些问题的答案,往往都不在软件本身,而在系统整体结构里。
如果你也来自软件领域,正在向工业自动化、设备开发、机器视觉或机器人方向过渡,希望这篇文章能帮你少走一些“只懂代码、不懂系统”的弯路。
在软件开发过程中,写出“能运行”的代码并不难,真正困难的是写出一段容易理解、容易维护、容易扩展,并且能够长期稳定运行的代码。随着项目规模不断扩大,代码往往会经历这样的变化。
最初,一个类可能只有几十行。逻辑简单,修改起来非常直接;但随着需求不断增加,功能不断堆叠,代码开始出现越来越多的问题:
这些问题并不是因为开发者能力不足,而是因为代码质量需要持续演进。C# 作为一门成熟的面向对象语言,提供了大量语言特性帮助我们编写更优雅、更安全的代码,例如泛型、委托、Lambda、LINQ、异步编程、特性(Attribute)、模式匹配等。但如果只是掌握语法,而没有形成良好的编程习惯,很容易写出“看起来能工作,但长期维护困难”的代码。
《C# 高效编程:改进 C# 代码的 50 个有效办法 第2版》这本书并不是单纯讲解 C# 语法,而是从工程实践角度,总结了大量能够改善代码质量的技巧和原则。
这些建议覆盖了多个方面:
接下来,我会结合书中的实践建议,并加入自己在项目开发中的理解,对这些技巧进行整理,希望能够帮助自己,也帮助更多 C# 开发者写出更加健壮、优雅的代码。
Node.js 的诞生,让 JavaScript 从浏览器的专属语言,跃升为构建高性能服务器的利器。凭借事件驱动的架构和非阻塞 I/O 特性,Node.js 成为现代网络应用开发中的重要基石。然而,当你写下 http.createServer时,是否好奇过这些简单的 API 背后究竟发生了什么?
本篇文章将带你深入 Node.js 的源码世界,揭开其核心模块、事件循环、异步模型和底层实现的神秘面纱。从 libuv 的非阻塞 I/O,到 V8 引擎对 JavaScript 的极速解析,我们将从代码的视角探索 Node.js 是如何在性能与灵活性之间找到绝佳平衡的。
无论你是想提升对 Node.js 的理解,还是希望从源码中汲取工程设计的智慧,这都将是一次充满收获的技术旅程。准备好了吗?让我们从入口文件开始,走进 Node.js 的源码迷宫!
我们经常说,Python 是一门解释型语言,但你知道它的解释器 CPython 究竟是如何工作的么?Python 的内存管理、字节码执行、垃圾回收……这些幕后英雄是如何协作的?在这篇文章中,我们将通过剖析 CPython 源码,一起探索 Python 的运行本质。
在学习 JavaScript 的过程中,我们可能会遇到一个经典问题:
|
|
在日常 C# 开发中,我们经常需要获取变量名、属性名、方法名或类型名的字符串形式,比如:
在 C# 6.0 之前,这些字符串往往是硬编码的魔法字符串(Magic String),维护成本极高。而 nameof 的出现,几乎是一次“工程级”的体验升级。
在开发日常工作中,文件下载看似是一个再普通不过的功能,但当下载规模扩大、速度需要优化、断点续传需要保证、并发控制需要精确、甚至要处理上百 GB 的大文件时,“下载器”就迅速从普通工具变成了一个考验系统设计能力的实战项目。Downloader 正是这样一个值得深入研究的优秀示例。它不仅实现了多线程下载、断点续传、分块合并、速度统计等核心功能,还在架构设计、并发模型、代码组织方式上体现了 C# 在现代并发场景下的最佳实践。对于正在学习 C# 并发编程、网络 IO、上位机开发的工程师来说,它几乎是一个“天然的进阶教材”。
当我们看到写得很漂亮的代码时,会很受启发。好代码会告很明确告诉你它在做什么。使用它会很有趣,并且会鼓励你把自己的代码写得更好。该书旨在帮助你把代码写得更好。该书的关键思想是代码应该写得容易理解。确切地说,使别人用最短的时间理解你的代码。每一章都会深入编程的某个方面来讨论如何使代码更容易理解。 该书分为四个部分:
在阅读 Vite 源码的过程中,我注意到一个有趣的依赖 —— launch-editor。起初只是随手点开,结果却发现它正是支撑起「浏览器报错信息 → 一键跳转到编辑器」这一开发体验的核心工具。其实,我们在使用 Vite、Vue CLI 等工具的时候,不止一次用过这个功能:报错时点击链接,代码编辑器立刻打开到对应的文件和行号。背后的关键实现,正是 launch-editor。
在前端开发的进化历程中,模块化 一直是一个核心问题。早期我们用全局变量、命名空间、立即执行函数(IIFE)来组织代码,但都存在依赖管理复杂、命名冲突等问题。 直到 ES6(ECMAScript 2015) 正式引入了 模块化语法,才为 JavaScript 带来了原生的模块方案。
Given an integer array nums sorted in non-decreasing order, remove some duplicates in-place such that each unique element appears at most twice. The relative order of the elements should be kept the same.
Since it is impossible to change the length of the array in some languages, you must instead have the result be placed in the first part of the array nums. More formally, if there are k elements after removing the duplicates, then the first k elements of nums should hold the final result. It does not matter what you leave beyond the first k elements.
Return k after placing the final result in the first k slots of nums.
Do not allocate extra space for another array. You must do this by modifying the input array in-place with O(1) extra memory.
在日常 Node.js 开发中,你有没有遇到过这样一个错误:
Error: EMFILE: too many open files
该错误通常出现在:批量文件操作、递归复制、日志处理等场景中。为什么会出现该错误?其实是因为在操作系统中每个进程最多可以同时打开一定数量的文件或 Socket, 而当打开的文件或 Socket 超过了这个限制时,就会出现“打开文件过多”的错误,导致程序突然崩溃。这种“打开文件过多”的问题看 似简单,但如果不加处理,尤其是在批量文件处理场景下,会让我们的 Node.js 程序非常脆弱。