python - 是否有 numpy / ndarrays 的包装器返回每个突变方法的数组?
问题描述
python
在对象发生突变后,显然numpy
不返回对象的决定是经常带来不便的根源。这个问题将基于一种不同的方法:使用一种builder
模式,以便我们可以这样做:
x = np.random.randint(0,10+1,50).sort()[:5]
并从一组随机的十个数字中得到至少五个值。相反,None
由于sort
. 我想知道是否有一个库可以builder
在顶部提供该模式,numpy
或者以某种方式强制所有突变numpy
方法返回self
而不是None
.
对于单个突变,该numpy
方法可能就足够了:
x = np.sort(np.random.randint(0,10+1,50))[:5]
但是scale
当需要一系列方法时,这种方法就不行了。例如
x = np.resize(np.sort(np.random.randint(0,10+1,50))[:5],[5,1])
这很快变得不仅难以编写而且难以阅读:我们被要求从右到左“由内而外”地编写和阅读代码。
更新下面宣布了“赢家”。稍作修改 - 为简洁起见将 from 重命名ChainWrapper
为- 以下是 a和 an ( ) Wrp
的用法:list
numpy
ndarray
Wrp(list(range(0,10,2))).append(8).append(10).insert(0, "hello").reverse().unwrap()[0:2]
# list:[10, 8]
import numpy as np
Wrp(np.linspace(0, 9, 10)).reshape(5, 2)[1:3, 0])
# np.array: array([2., 4.])
重点是 : append
,insert
reverse
然后reshape
返回 None 。Wrp
检测到并self
返回。我经常想编写一个对列表执行多个操作的 lambda。没有上述内容是不可能做到的。
解决方案
不返回变异对象是一种 Python 主义,它提醒您没有创建新对象这一事实。None
由于这个原因,几乎所有执行内部突变的标准库函数都会返回。
您可以编写自己的包装器(并使用一些getattr
魔法,使其自动化),但这可能不太值得。
编辑:如果你需要这个只是为了链接,你可以做类似的事情
def chain(a, f):
f(a)
return a
x = chain(
np.random.randint(0,10+1,50),
lambda m: m.sort(),
)[:5]
甚至更高级,
def hyperchain(val, *fs):
for f in fs:
res = f(val)
if res is not None:
val = res
return val
让你链接价值返回的东西和无返回的东西:
x = hyperchain(
np.random.randint(0,10+1,50),
lambda m: m.sort(),
lambda m: m[:5],
)
编辑2:这是前面提到的getattr
包装想法——并不是说这是一个好主意或完美,但我们开始吧:
from functools import wraps
class ChainWrapper:
def __init__(self, target):
self._target = target
def __getattr__(self, key):
attr = getattr(self._target, key)
if callable(attr):
@wraps(attr)
def wrapped_func(*args, **kwargs):
retval = attr(*args, **kwargs)
if retval is None:
retval = self
return retval
return wrapped_func
return attr
def __str__(self):
return self._target.__str__()
def __repr__(self):
return f"<chain-wrapped {self._target!r}"
def unwrap(self):
return self._target
# TODO: implement other things such as __getitem__ and __setitem__
# to just proxy through
l = [1, 2, 4, 8]
lw = ChainWrapper(l)
print(lw.append(8).append(10).insert(0, "hello").reverse())
这输出
[10, 8, 8, 4, 2, 1, 'hello']
推荐阅读
- css - 防止折叠的 bootstrap4 导航栏中的下拉列表扩展导航栏
- vba - 一次将整个集合移调到一个范围
- javascript - 如何在数组中推送新对象?
- android - Activity 到 Android 库的通信选项 (IPC)
- javascript - 浏览器中的 API 响应与代码中的响应不同
- android - Chrome cast 会话启动失败并出现错误 15
- sql-server - 将 SQL Server 日期字符串更改为其他格式
- c++ - 有没有办法在 GLFW 中删除 60 fps 上限?
- c++ - 无法从 nautilus 运行可执行文件
- spring - Spring boot,mongo DB如何比较大于0的列值