Dataclass 代码,在 Python 版本允许的情况下将 slots 设置为 true。

huangapple go评论58阅读模式
英文:

Dataclass code that sets slots=true if python version allows

问题

I'm writing a module that needs to run under both Python 3.8 and Python 3.10. I want to have dataclasses that have slots (@dataclasses.dataclass(slots=True)) in Python 3.10 for the purposes of type checking (both static and runtime). Is there a from __future__ import that will make this compatible with Python 3.8? If not, what is the most pytype-friendly way of emulating one?

Additional note: I'm currently using the dataclasses_json module, which to the best of my knowledge is not compatible with attrs. Otherwise I could switch from dataclasses to attrs and easily solve the problem.

英文:

I'm writing a module that needs to run under both Python 3.8 and Python 3.10. I want to have dataclasses that have slots (@dataclasses.dataclass(slots=True)) in Python 3.10 for the purposes of type checking (both static and runtime). Is there a from __future__ import that will make this compatible with Python 3.8? If not, what is the most pytype-friendly way of emulating one?

Additional note: I'm currently using the dataclasses_json module, which to the best of my knowledge is not compatible with attrs. Otherwise I could switch from dataclasses to attrs and easily solve the problem.

答案1

得分: 3

如果您不需要在旧版本中使用slots功能,那很容易。

from __future__ ... 导入保留用于更改语法本身工作方式的语言特性。dataclasses中的slots功能只是库中的另一个参数,因此从逻辑上讲,它不会获得这样的解决方法。

目前,必须根据装饰器调用有条件地插入slots参数。Python 3.8的装饰器表达式与一般表达式不同,但我们可以将内联逻辑添加到仅参数部分,这在调用本身之前执行,因此它会起作用。

Python还没有直接在调用中根据条件添加关键字参数的语法,但由于可以使用**从字典中提取关键字参数,所以可以间接实现。因此,下面的代码应该有效:

import dataclasses
import sys
...

py310 = sys.version_info.minor >= 10 or sys.version_info.major > 3

@dataclasses.dataclass(**({"slots": True} if py310 else {}))
class MyData:
   ...
英文:

If you don't need the slots feature in the older version, that is easy.

from __future__ ... imports as reserved for language features that change the way the syntax itself works. The slots feature in dataclasses is just another parameter in the library, so, logically, it does not get such a workaround.

As it is, one have to conditionally insert the slots argument on the decorator call. Python 3.8 decorator expressions are not the same as general expressions - but we can add the inline logic to the arguments part only - that is executed before the call itself, so it will work.

Python also has no syntax to directly add a keyword parameter in a call or not, according to a condition - but since keyword parameters can be extracted from dictionaries with the use of **, it can be done indirectly.

Therefore, the lines bellow should work:

import dataclasses
import sys
...

py310 = sys.version_info.minor >= 10 or sys.version_info.major > 3

@dataclasses.dataclass(**({"slots": True} if py310 else {}))
class MyData:
   ...

huangapple
  • 本文由 发表于 2023年3月7日 06:51:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75656549.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定