【问题标题】:How to force the type of a scalar in python如何在python中强制标量的类型
【发布时间】:2016-01-06 21:06:18
【问题描述】:

我想定义一个变量并让 python 在所有操作中尊重该变量的类型。例如,numpy 数组对所有操作强制其元素的类型,因此会发生以下情况:

>> import numpy as np
>> foo = np.array([0], dtype=np.uint8)
>> foo[0] = 255
>> foo[0]
255
>> foo[0] += 1
>> foo[0]
0
>> foo[0] = -3
253

这种行为正是我想要的,但对于标量值,我不必为每个操作创建一个包含 1 个元素的数组并索引到该数组。我也不想在每个操作上都强制转换值。

这就是我想要的:

>> foo = np.uint8(0)
>> foo = 257
>> foo
1
>> foo = -1
255

这可能吗?

解决原因:我正在编写一个硬件模拟器,需要模拟固定大小的内存/寄存器(8 位)的行为,并希望对这些变量进行操作并让它们表现得像真正的 8 位内存

这已被标记为 Python: confusion between types and dtypes 的副本,但我对类型并不感到困惑,我希望标量的行为类似于 uint8,而无需为每个操作显式转换它,我想知道这是否可能。我宁愿避免输入:

>> foo = np.uint8(value)
>> foo = np.uint8(foo + number)
>> foo += np.uint8(number)

这很乏味且容易出错,如果我可以定义类型(或类似于类型的东西,请不要在这里误用类型一词而感到困惑,我只对实现感兴趣)无需过多输入或强制转换即可获得所需的行为)并继续编写我的模拟器。

【问题讨论】:

  • 感谢 fjarri,但我对这些类型并不感到困惑。我试图在操作标量时获得特定行为,并希望无需过多输入或强制转换就可以实现。
  • 嗯,这就是numpy 伙计们做出的设计选择,正如this answer 中提到的那样。您看到自己获得了数组所需的行为,但标量却没有。至于foo = -1 的构造,在进行此分配时,不可能让Python 考虑foo 的当前类型(除非您正在做一些AST 魔术)。 foo 无论如何都会被int 类型的文字-1 覆盖。

标签: python numpy types casting scalar


【解决方案1】:

在 Python 中,您不能声明变量的类型。变量foo 没有类型。它可以有一个值,并且该值有一个类型(或类)。对象有类型,变量没有。

>> foo = np.uint8(0)   # gives foo one value
>> foo = 257   # gives it another, unrelated value, of type 'int'
>> foo     # doesn't work this way
1
>> foo = -1   # another integer
255

您可以定义一个具有这种行为的类,例如:

class Uint8(object):
    def __init__(self, value):
        self.value = value % 256
foo = Uint8(0)
foo = Uint8(257)
foo = Uint8(-1)

您的 numpy 示例有效,因为 numpy 定义了 uint8 类型。而像foo[0] = 257 这样的表达式会修改现有变量。他们不会为foo 分配新值。对可变和不可变对象的回顾可能会有所帮助。列表、字典和数组是可变的;字符串、元组和整数是不可变的。

>> foo = np.array([0], dtype=np.uint8)
>> foo[0] = 255
>> foo[0]
255
>> foo[0] += 1

【讨论】:

    【解决方案2】:

    您可以通过 Numpy 的索引数组标量功能来做到这一点:

    foo = np.array(0, dtype=np.uint8)  # or np.zeros((), dtype=np.uint8)
    foo[()] = -1
    foo
    

    输出为array(255, dtype=uint8)

    【讨论】:

      猜你喜欢
      • 2017-11-30
      • 2010-10-19
      • 1970-01-01
      • 1970-01-01
      • 2023-01-25
      • 2018-05-15
      • 2021-05-16
      • 1970-01-01
      • 2021-10-03
      相关资源
      最近更新 更多