英文:
Unexpected type warning in `__new__` method for `int` subclass
问题
以下是翻译好的部分:
以下是翻译好的部分:
以下代码:
```python
class Foo(int):
def __new__(cls, x, *args, **kwargs):
x = x if isinstance(x, int) else 42
return super(Foo, cls).__new__(cls, x, *args, **kwargs)
在PyCharm中产生警告:“期望类型为'str | bytes | bytearray',但实际为'int'
”在最后一行的x
上。
为什么会这样?
如果我评估super(Size, cls).__new__ == int.__new__
,结果是True
。这不也期望一个int
吗?
如果我想在首次分配值或将某个值强制转换为此类型时添加行为,是否有更好的方法来创建int
的子类?
这样的类的具体示例是class Size(int)
,可以实例化为Size(1024)
或Size('1 KiB')
,结果相同。
<details>
<summary>英文:</summary>
The following code:
class Foo(int):
def new(cls, x, *args, **kwargs):
x = x if isinstance(x, int) else 42
return super(Foo, cls).__new__(cls, x, *args, **kwargs)
Results in a warning (in PyCharm): "`Expected type 'str | bytes | bytearray', got 'int' instead`" on `x` in the last line.
Why is this?
If I evaluate `super(Size, cls).__new__ == int.__new__`, the result is `True`. Wouldn't that expect an `int` as well?
Is there a better way to create a subclass of `int`, if I want to add behaviour when a value is first assigned or some value is cast to this type?
A concrete example of such a class would be a `class Size(int)` that could be instantiated as `Size(1024)` or `Size('1 KiB')`, with the same result.
</details>
# 答案1
**得分**: 2
The overload of `int` with multiple args takes a string as the first param. It is roughly equivalent to
```python
int(x:int = 0) -> int:
int(x:str, base: int = 10) -> int:
You are providing __new__(cls, x, *args, **kwargs)
, so it is expecting that there should be a string as the first param.
So for this to not complain, drop the extra args:
class Foo(int):
def __new__(cls, x):
x = x if isinstance(x, int) else 42
return super(Foo, cls).__new__(cls, x)
print(Foo(2))
print(Foo("2"))
2
42
英文:
The overload of int
with multiple args takes a string as the first param. It is roughly equivalent to
int(x:int = 0) -> int:
int(x:str, base: int = 10) -> int:
You are providing __new__(cls, x, *args, **kwargs)
, so it is expecting that there should be a string as the first param.
So for this to not complain, drop the extra args:
class Foo(int):
def __new__(cls, x):
x = x if isinstance(x, int) else 42
return super(Foo, cls).__new__(cls, x)
print(Foo(2))
print(Foo("2"))
2
42
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论