我的印象是,只能用字母和_开头变量名,但是在进行测试时,我还发现可以用$开头变量名,如下所示:
#include <stdio.h>
int main() {
int myvar=13;
int $var=42;
printf("%d\n", myvar);
printf("%d\n", $var);
}
Run Code Online (Sandbox Code Playgroud)
13
42
Run Code Online (Sandbox Code Playgroud)
根据此资源,它说您不能在C中以$开头变量名,这是错误的(至少在使用我的gcc版本Apple LLVM版本10.0.1(clang-1001.0.46.4)进行编译时)。我在网上找到的其他资源似乎也表明变量不能以$开头,这就是为什么我感到困惑的原因。
这些文章难道没有提到这个细微差别吗?如果是,为什么这是C的功能?
我已经阅读了很多关于 Python 导入(以及相关的 SO 问题)的“操作方法”文章,但是我正在努力弄清楚在大型 Python 项目中管理导入的“最佳实践”是什么。例如,假设我有一个如下所示的项目结构(这是一个过度简化):
test/
packA/
subA/
__init__.py
sa1.py
sa2.py
__init__.py
a1.py
a2.py
packB/
b1.py
b2.py
main.py
Run Code Online (Sandbox Code Playgroud)
并在里面说packA/subA/sa1.py我想从packB/b1.py. 更一般地说,我希望能够在项目内的包/子包之间自由导入。
根据我目前的理解,有四种方法可以做到这一点:
将我的项目根永久添加到 PYTHONPATH 并在项目中的任何地方使用绝对导入。所以在 packA/subA/sa1.py 里面我会有
from packB import b1
随着项目树变大,这可能会变得有点混乱,例如
from packB.subC.subD.subE import f1
与上面相同,但我没有修改 PYTHONPATH 以包含项目根目录,而是坚持只从项目根目录执行 python(以便根目录始终是工作目录)。
使用相对导入
from ...packB import b1
我不喜欢这样,因为它不容易阅读,而且我读过的所有地方都说相对导入是个坏主意。
使用 setuptools/setup.py 脚本并使用 pip 安装我的包,以便我可以在任何地方导入。
这似乎有点矫枉过正,因为所有代码都已经在项目文件夹中(并且每次包更改时都必须重新安装),并且还可能导致依赖项/版本管理的麻烦。
所以我的问题是,以上哪一个(如果有)被认为是最佳实践?我目前在 1 和 2 之间犹豫不决,但很高兴听到更优雅/Pythonic 的方法。
注意:我使用的是 Python 3.6
我注意到,双方scipy并sklearn有余弦相似度/余弦距离函数。我想测试每个向量对的速度:
setup1 = "import numpy as np; arrs1 = [np.random.rand(400) for _ in range(60)];arrs2 = [np.random.rand(400) for _ in range(60)]"
setup2 = "import numpy as np; arrs1 = [np.random.rand(400) for _ in range(60)];arrs2 = [np.random.rand(400) for _ in range(60)]"
import1 = "from sklearn.metrics.pairwise import cosine_similarity"
stmt1 = "[float(cosine_similarity(arr1.reshape(1,-1), arr2.reshape(1,-1))) for arr1, arr2 in zip(arrs1, arrs2)]"
import2 = "from scipy.spatial.distance import cosine"
stmt2 = "[float(1 - cosine(arr1, arr2)) for arr1, arr2 in zip(arrs1, arrs2)]"
import timeit
print("sklearn: …Run Code Online (Sandbox Code Playgroud) 假设我有以下特征Stack,它简单地定义了popandpush操作:
trait Stack<T> {
fn push(&mut self, data: T);
fn pop(&mut self) -> Option<T>;
}
Run Code Online (Sandbox Code Playgroud)
我可以使用以下方法测试我的特征的任何给定实现:
fn test(stack: &mut dyn Stack<i32>) {
stack.push(1);
stack.push(2);
stack.push(3);
assert_eq!(stack.pop(), Some(3));
assert_eq!(stack.pop(), Some(2));
assert_eq!(stack.pop(), Some(1));
assert_eq!(stack.pop(), None);
}
Run Code Online (Sandbox Code Playgroud)
例如,这是一个在底层使用向量的实现:
fn test(stack: &mut dyn Stack<i32>) {
stack.push(1);
stack.push(2);
stack.push(3);
assert_eq!(stack.pop(), Some(3));
assert_eq!(stack.pop(), Some(2));
assert_eq!(stack.pop(), Some(1));
assert_eq!(stack.pop(), None);
}
Run Code Online (Sandbox Code Playgroud)
我们可以使用我们的test函数进行测试:
struct StackWithVec<T> {
vec: Vec<T>,
}
impl<T> Stack<T> for StackWithVec<T> {
fn push(&mut self, data: T) { …Run Code Online (Sandbox Code Playgroud) 我有一个功能:
fn foo<i32>(x: i32) -> Result<i32, i32> {
...
}
Run Code Online (Sandbox Code Playgroud)
我想将结果的值提取到一个变量中,无论它是Ok或Err。我可以这样做:
let val = match foo(10) {
Ok(i) => i,
Err(i) => i,
}
Run Code Online (Sandbox Code Playgroud)
想知道是否有一种“更干净”或更“惯用”的方式来这样做,或者这是否是最好的方式。
注意:用例是二分搜索,其中我有一个通用函数,Ok(i)如果找到匹配项,它会返回索引,否则它会返回Err(i)您插入目标以保持数组排序的索引。但是,我不想公开这个通用函数,而是公开两个变体binary_search和binary_search_insert_index。首先,我只是返回iif Ok(i)else None。对于第二个,i无论如何我都会返回。
python ×2
rust ×2
c ×1
naming ×1
project ×1
python-3.x ×1
scikit-learn ×1
scipy ×1
variables ×1