Python 3.5 带给我们的方便的矩阵以及其他改进
Python

> 
> 探索一些未被充分利用但仍然有用的 Python 特性。
> 
> 
> 


![](/data/attachment/album/202106/01/201953lua9t9f3vvwqbqet.jpg "Hacker code matrix")


这是 Python 3.x 首发特性系列文章的第六篇。Python 3.5 在 2015 年首次发布，尽管它已经发布了很长时间，但它引入的许多特性都没有被充分利用，而且相当酷。下面是其中的三个。


### @ 操作符


`@` 操作符在 Python 中是独一无二的，因为在标准库中没有任何对象可以实现它！它是为了在有矩阵的数学包中使用而添加的。


矩阵有两个乘法的概念。元素积是用 `*` 运算符完成的。但是矩阵组合（也被认为是乘法）需要自己的符号。它是用 `@` 完成的。


例如，将一个“八转”矩阵（将轴旋转 45 度）与自身合成，就会产生一个四转矩阵。



```
import numpy

hrt2 = 2**0.5 / 2
eighth_turn = numpy.array([
    [hrt2, hrt2],
    [-hrt2, hrt2]
])
eighth_turn @ eighth_turn

```


```
    array([[ 4.26642159e-17,  1.00000000e+00],
           [-1.00000000e+00, -4.26642159e-17]])

```

浮点数是不精确的，这比较难以看出。从结果中减去四转矩阵，将其平方相加，然后取其平方根，这样就比较容易检查。


这是新运算符的一个优点：特别是在复杂的公式中，代码看起来更像基础数学：



```
almost_zero = ((eighth_turn @ eighth_turn) - numpy.array([[0, 1], [-1, 0]]))**2
round(numpy.sum(almost_zero) ** 0.5, 10)

```


```
    0.0

```

### 参数中的多个关键词字典


Python 3.5 使得调用具有多个关键字-参数字典的函数成为可能。这意味着多个默认值的源可以与更清晰的代码”互操作“。


例如，这里有个可笑的关键字参数的函数：



```
def show_status(
    *,
    the_good=None,
    the_bad=None,
    the_ugly=None,
    fistful=None,
    dollars=None,
    more=None
):
    if the_good:
        print("Good", the_good)
    if the_bad:
        print("Bad", the_bad)
    if the_ugly:
        print("Ugly", the_ugly)
    if fistful:
        print("Fist", fistful)
    if dollars:
        print("Dollars", dollars)
    if more:
        print("More", more)

```

当你在应用中调用这个函数时，有些参数是硬编码的：



```
defaults = dict(
    the_good="You dig",
    the_bad="I have to have respect",
    the_ugly="Shoot, don't talk",
)

```

从配置文件中读取更多参数：



```
import json

others = json.loads("""
{
"fistful": "Get three coffins ready",
"dollars": "Remember me?",
"more": "It's a small world"
}
""")

```

你可以从两个源一起调用这个函数，而不必构建一个中间字典：



```
show_status(**defaults, **others)

```


```
    Good You dig
    Bad I have to have respect
    Ugly Shoot, don't talk
    Fist Get three coffins ready
    Dollars Remember me?
    More It's a small world

```

### os.scandir


`os.scandir` 函数是一种新的方法来遍历目录内容。它返回一个生成器，产生关于每个对象的丰富数据。例如，这里有一种打印目录清单的方法，在目录的末尾跟着 `/`：



```
for entry in os.scandir(".git"):
    print(entry.name + ("/" if entry.is_dir() else ""))

```


```
    refs/
    HEAD
    logs/
    index
    branches/
    config
    objects/
    description
    COMMIT_EDITMSG
    info/
    hooks/

```

### 欢迎来到 2015 年


Python 3.5 在六年前就已经发布了，但是在这个版本中首次出现的一些特性非常酷，而且没有得到充分利用。如果你还没使用，那么将他们添加到你的工具箱中。




---


via: <https://opensource.com/article/21/5/python-35-features>


作者：[Moshe Zadka](https://opensource.com/users/moshez) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


OK
This is the sixth in a series of articles about features that first appeared in a version of Python 3.x. Python 3.5 was first released in 2015, and even though it has been out for a long time, many of the features it introduced are underused and pretty cool. Here are three of them.

## The @ operator


The `@`

operator is unique in Python in that there are no objects in the standard library that implement it! It was added for use in mathematical packages that have matrices.

Matrices have two concepts of multiplication; point-wise multiplication is done with the `*`

operator. But matrix composition (also considered multiplication) needed its own symbol. It is done using `@`

.

For example, composing an "eighth-turn" matrix (rotating the axis by 45 degrees) with itself results in a quarter-turn matrix:

```
import numpy
hrt2 = 2**0.5 / 2
eighth_turn = numpy.array([
[hrt2, hrt2],
[-hrt2, hrt2]
])
eighth_turn @ eighth_turn
```


```
array([[ 4.26642159e-17, 1.00000000e+00],
[-1.00000000e+00, -4.26642159e-17]])
```


Floating-point numbers being imprecise, this is harder to see. It is easier to check by subtracting the quarter-turn matrix from the result, summing the squares, and taking the square root.

This is one advantage of the new operator: especially in complex formulas, the code looks more like the underlying math:

```
almost_zero = ((eighth_turn @ eighth_turn) - numpy.array([[0, 1], [-1, 0]]))**2
round(numpy.sum(almost_zero) ** 0.5, 10)
```


` 0.0`


## Multiple keyword dictionaries in arguments

Python 3.5 made it possible to call functions with multiple keyword-argument dictionaries. This means multiple sources of defaults can "co-operate" with clearer code.

For example, here is a function with a ridiculous amount of keyword arguments:

```
def show_status(
*,
the_good=None,
the_bad=None,
the_ugly=None,
fistful=None,
dollars=None,
more=None
):
if the_good:
print("Good", the_good)
if the_bad:
print("Bad", the_bad)
if the_ugly:
print("Ugly", the_ugly)
if fistful:
print("Fist", fistful)
if dollars:
print("Dollars", dollars)
if more:
print("More", more)
```


When you call this function in the application, some arguments are hardcoded:

```
defaults = dict(
the_good="You dig",
the_bad="I have to have respect",
the_ugly="Shoot, don't talk",
)
```


More arguments are read from a configuration file:

```
import json
others = json.loads("""
{
"fistful": "Get three coffins ready",
"dollars": "Remember me?",
"more": "It's a small world"
}
""")
```


You can call the function from both sources together without having to construct an intermediate dictionary:

`show_status(**defaults, **others)`


```
Good You dig
Bad I have to have respect
Ugly Shoot, don't talk
Fist Get three coffins ready
Dollars Remember me?
More It's a small world
```


## os.scandir

The `os.scandir`

function is a new way to iterate through directories' contents. It returns a generator that yields rich data about each object. For example, here is a way to print a directory listing with a trailing `/`

at the end of directories:

```
for entry in os.scandir(".git"):
print(entry.name + ("/" if entry.is_dir() else ""))
```


```
refs/
HEAD
logs/
index
branches/
config
objects/
description
COMMIT_EDITMSG
info/
hooks/
```


## Welcome to 2015

Python 3.5 was released over six years ago, but some of the features that first showed up in this release are cool—and underused. Add them to your toolkit if you haven't already.

## Comments are closed.