小编flo*_*lla的帖子

bash函数:将主体括在括号和括号中

通常,使用花括号来定义bash函数来包围正文:

foo()
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

今天在处理shell脚本时大量使用函数时,我遇到的问题是调用函数中调用的名称相同的变量,即那些变量是相同的.然后我发现可以通过将函数内部的局部变量定义为local来防止这种情况:local var=xyz.

然后,在某些时候,我发现了一个线程(使用括号而不是大括号定义bash函数体),其中解释了使用括号来定义函数同样有效:

foo()
(
    ...
)
Run Code Online (Sandbox Code Playgroud)

这样做的结果是函数体在子shell中执行,这有利于函数具有自己的变量范围,这允许我在没有本地的情况下定义它们.由于具有函数局部范围似乎更有意义,并且比所有变量全局更安全,我立即问自己:

  • 为什么默认情况下使用大括号括起函数体而不是括号?

但是,我很快发现了在子shell中执行该函数的一个主要缺点,特别是从函数内部退出脚本不再起作用,而是迫使我在整个调用树中使用返回状态(如果是嵌套函数).这引出了我的后续问题:

  • 使用括号而不是大括号是否还有其他主要缺点(*)(这可能解释为什么大括号似乎更受欢迎)?

(*)我知道(从异常相关的讨论中我偶然发现),有些人认为明确使用错误状态比从任何地方退出要好得多,但我更喜欢后者.

显然这两种风格都有其优点和缺点.所以我希望你们中有些经验丰富的bash用户可以给我一些一般指导:

  • 我何时应该使用花括号来包围函数体,何时可以切换到括号?

编辑:从答案的转移

谢谢你的回答,我的脑袋现在对此更加清晰.所以我从答案中得到的是:

  • 坚持传统的花括号,如果只是为了不混淆脚本的其他潜在用户/开发者(如果整个身体被括在括号中,甚至使用括号).

  • 花括号的唯一真正缺点是可以更改父作用域中的任何变量,尽管在某些情况下这可能是一个优点.通过将变量声明为可以很容易地避免这种情况local.

  • 另一方面,使用括号可能会产生一些严重的不良影响,例如搞乱退出,导致杀死脚本的问题以及隔离变量范围.

bash function curly-braces parentheses

27
推荐指数
3
解决办法
6489
查看次数

vimdiff:强制逐行比较(忽略所谓的缺失/额外行)

如何强制vimdiff始终逐行比较两个文件而不识别添加或删除的行?

问题是,如果两个文件之间的差异很大,但是文件中的两行偶然匹配,vimdiff认为这些行是相同的,只是将其余行视为添加或删除的行,并且生成的diff完全不可用.在我的例子中,file1中的第i行始终对应于file2中的第i行,因此vimdiff没有添加或删除行的业务查找.

以下是一个小例子,其中两个文件包含两个变量的值,每个变量三次.Vimdiff错误地将file1/line1与file2/line3匹配,并认为已经添加或删除了它周围的一些行.差异(减去颜色)然后看起来像这样:

              |  1 foo 8.1047  < del/new
              |  2 bar 6.2343  < del/new
1 foo 0.0000  |  3 foo 0.0000  < match
2 bar 5.3124  |  4 bar 1.4452  < wrong
3 foo 4.5621  |                < new/del
4 bar 6.3914  |                < new/del
5 foo 1.0000  |  5 foo 1.0000  < match
6 bar 6.3212  |  6 bar 7.2321  < wrong
Run Code Online (Sandbox Code Playgroud)

但是,我想要的是以下内容,除了匹配的行5之外,所有行都标记为错误:

1 foo 0.0000  |  1 foo 8.1047 < wrong
2 bar 5.3124  |  2 bar 6.2343 …
Run Code Online (Sandbox Code Playgroud)

vim diff vimdiff

12
推荐指数
2
解决办法
4432
查看次数

如何强制dicts无序(用于测试)?

我只花了半天的时间追踪一个错误到一个dict,我在迭代它时忘了排序.尽管测试了那部分代码,但是测试没有提到它,因为测试期间dict具有可重复的顺序.只有当我洗牌时,测试才会失败!(我使用了一个中间random.shuffle'd列表并构建了一个OrderedDict)

这有点吓到我,因为整个地方可能都有类似的错误!

有没有办法在测试期间全局强制所有dicts无序?

更新:我想我至少弄明白是什么导致了这个错误.作为描述在这里,为int键类型的字典通常排序,但可能并不总是.我的假设:在我的测试中,整数总是很小(10阶),因此总是有序.然而,在实际运行中,整数更大(订单10 ^ 13),因此并不总是有序.我能够在交互式会话中重现这种行为:list(foo.keys()) == sorted(foo.keys())总是True用于小键,但不是每个具有非常大的键的dict.

python unit-testing python-3.x

8
推荐指数
1
解决办法
90
查看次数

有效地在非矩形2D网格上找到最近点的索引

我有一个不规则的(非矩形)lon/lat网格和lon/lat坐标中的一堆点,它们应该对应于网格上的点(尽管由于数值原因它们可能略微偏离).现在我需要相应的lon/lat点的索引.

我已经编写了一个函数来执行此操作,但它确实很慢.

def find_indices(lon,lat,x,y):
    lonlat = np.dstack([lon,lat])
    delta = np.abs(lonlat-[x,y])
    ij_1d = np.linalg.norm(delta,axis=2).argmin()
    i,j = np.unravel_index(ij_1d,lon.shape)
    return i,j

ind = [find_indices(lon,lat,p*) for p in points]
Run Code Online (Sandbox Code Playgroud)

我很确定在numpy/scipy中有更好(更快)的解决方案.我已经谷歌搜索了很多,但到目前为止我的答案还没有找到.

有关如何有效找到相应(最近)点的指数的任何建议?

PS:这个问题来自另一个问题(点击).

编辑:解决方案

根据@Cong Ma的回答,我找到了以下解决方案:

def find_indices(points,lon,lat,tree=None):
    if tree is None:
        lon,lat = lon.T,lat.T
        lonlat = np.column_stack((lon.ravel(),lat.ravel()))
        tree = sp.spatial.cKDTree(lonlat)
    dist,idx = tree.query(points,k=1)
    ind = np.column_stack(np.unravel_index(idx,lon.shape))
    return [(i,j) for i,j in ind]
Run Code Online (Sandbox Code Playgroud)

为了解决这个问题以及Divakar的答案中的问题,下面是我使用find_indices的功能的一些时间(以及它在速度方面的瓶颈)(参见上面的链接):

spatial_contour_frequency/pil0                :   331.9553
spatial_contour_frequency/pil1                :   104.5771
spatial_contour_frequency/pil2                :     2.3629
spatial_contour_frequency/pil3                :     0.3287
Run Code Online (Sandbox Code Playgroud)

pil0是我最初的方法,pil1Divakar和pil2/ pil3 …

python performance interpolation numpy scipy

5
推荐指数
1
解决办法
1286
查看次数

测试:比较 numpy 数组,同时允许一定的不匹配

我有两个 numpy 数组,其中包含我正在与numpy.testing.assert_array_equal. 数组“足够相等”,即一些元素不同,但考虑到我的数组的大小,没关系(在这种特定情况下)。但当然测试失败了:

AssertionError:
Arrays are not equal

(mismatch 0.0010541406645359075%)
 x: array([[ 0.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0.,  0.,  0., ...,  0.,  0.,  0.],...
 y: array([[ 0.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0.,  0.,  0., ...,  0.,  0.,  0.],...

----------------------------------------------------------------------
Ran 1 test in 0.658s

FAILED (failures=1)
Run Code Online (Sandbox Code Playgroud)

当然,有人可能会争辩说,(长期)干净的解决方案是调整参考解决方案或诸如此类的东西,但我更喜欢简单地允许一些不匹配而不会导致测试失败。我本来希望 assert_array_equal 有一个选项,但事实并非如此。

我编写了一个函数,它允许我完全按照自己的意愿行事,因此问题可能被认为已解决,但我只是想知道是否有更好、更优雅的方法来做到这一点。此外,解析错误字符串的方法感觉很hacky,但我还没有找到更好的方法来获取不匹配百分比值。

def assert_array_equal_tolerant(arr1,arr2,threshold):
    """Compare …
Run Code Online (Sandbox Code Playgroud)

python arrays testing numpy

5
推荐指数
1
解决办法
1283
查看次数

python:相对导入的别名

是否可以使用相对导入导入具有别名的同一包的模块?

说我有以下包结构:

lib/
    foobar/
        __init__.py
        foo.py
        bar.py
Run Code Online (Sandbox Code Playgroud)

而在foo.py,我想用从bar.py的东西,但我想用它作为"bar.my_function",所以不是from .bar import my_function,我试过import .bar as barimport .bar,这两者不工作(语法异常无效).我已经尝试了pythhon2.7和python3.4(后者是我的目标版本).

然而,什么工作,以及我现在使用的是import foobar.bar as bar,即绝对导入而不是相对.这是一个很好的解决方案,因为我不希望更改包名称(即使它确实如此,代码中也没有太多变化),但如果我可以使用相对导入来完成此操作会很好!

摘要:

#import .bar as bar # why not?!?
#import .bar # shot in the dark
import foobar.bar as bar # current solution
Run Code Online (Sandbox Code Playgroud)

python python-import

4
推荐指数
1
解决办法
1065
查看次数

python:将多边形转换为掩码数组

我有一个多边形,我想变成一个掩模数组,这样所有落在多边形内/外的点都是True/False.我以为我找到了完美的解决方案(SciPy创建2D多边形面具),但由于某种原因,这不起作用!

我究竟做错了什么?

#!/usr/bin/env python3

import numpy as np
import scipy as sp
from PIL import Image, ImageDraw

nx, ny = 10, 10

poly = np.array([(1, 1), (6, 2), (9, 9), (3, 7)])

img = Image.new("L", [nx, ny], 0)
ImageDraw.Draw(img).polygon(poly, outline=1, fill=1)
mask = np.array(img)

print(mask)
# [[1 0 0 0 0 0 0 0 0 0]
#  [0 0 0 0 0 0 0 0 0 0]
#  [0 0 0 0 0 0 0 0 0 0] …
Run Code Online (Sandbox Code Playgroud)

python numpy scipy point-in-polygon python-imaging-library

3
推荐指数
1
解决办法
2507
查看次数