提问人:Abdulrahman Sheikho 提问时间:10/10/2023 最后编辑:Abdulrahman Sheikho 更新时间:10/11/2023 访问量:59
混合使用可变/不可变的“数据容器”python
Having a mix of mutable/immutable "data container" python
问:
我想知道是否有办法在相同的“数据容器”中定义可变/不可变/默认值的值。
我所说的“数据容器”是指任何像 、 、 、tuple
dict
class
Enum
dataclass
这个例子清楚地表明了我的观点:
如果我想拥有 as 值。Page
first_page
current_page
last_page
如果我使用该方法,则实现将是这样的:dataclass
from dataclasses import dataclass
@dataclass(slots=True)
class Pages:
first_page: int = 0 # need to be immutable
current_page: int # need to be initialized and mutable
last_page: int # need to be initialized and immutable
这能做到吗?或者有没有办法做到这一点?
答:
0赞
Matt Pitkin
10/10/2023
#1
对于类,您可以使用 getter 和 setter。例如,要保持不可变,您可以创建一个名为(在 Python 中实际上不是私有的)的准私有属性,您可以通过 (getter) 属性属性访问该属性:first_page
_first_page
first_page
class Pages:
_first_page: int = 0
@property
def first_page(self):
return self._first_page
有了这个,你可以得到 ,但如果你尝试设置,你会得到一个:first_page
first_page
AttributeError
p = Pages()
print(p.first_page)
0
p.first_page = 2
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[17], line 1
----> 1 p.first_page = 2
AttributeError: can't set attribute
你可以有一个等效的属性,它显式返回一条消息,该消息是不可变的,什么都不做,例如:setter
first_page
class Pages:
_first_page: int = 0
@property
def first_page(self):
return self._first_page
@first_page.setter
def first_page(self, _):
print("first_pass is immutable")
pass
对于要可变的值,可以像往常一样设置类属性,或者(如上所述)使用 和 修饰函数来设置等效的准私有属性。@property
@setter
评论
0赞
Abdulrahman Sheikho
10/11/2023
我知道我可以使用通常的类实现来解决我的问题。也许我很懒惰,正在寻找一种简单明了的方法,因为使用它们清楚地说明了为什么我使用它们与普通课程不同。 另外,我知道这一点,并且更快,更容易制作。enum
dataclass
enum
tuple
0赞
Yuri R
10/11/2023
#2
您可以使用 from 。field
dataclasses
@dataclass(frozen=True) # Making the dataclass frozen makes its fields immutable.
class Pages:
_last_page: int = field(repr=False) # Private field, and won't be shown in repr.
_first_page: int = field(default=0, repr=False)
current_page: int = field(default_factory=int, hash=False) # Making it mutable by setting hash to False.
@property
def first_page(self) -> int: # Property for the first_page to allow only reading.
return self._first_page
@property
def last_page(self) -> int: # Property for the last_page to allow only reading.
return self._last_page
测试
p = Pages(current_page=5, _last_page=10)
print(p.first_page) # 0
print(p.current_page) # 5
print(p.last_page) # 10
# This will raise an exception: dataclasses.FrozenInstanceError
# p.first_page = 2
确保除非另有指定,否则属性保持不可变。frozen=True
评论
0赞
Abdulrahman Sheikho
10/11/2023
但是通过分配这个值会使整体不可变,并且尝试更改为另一个值会提高frozen=True
Pages
current_page
dataclasses.FrozenInstanceError
0赞
link89
10/11/2023
#3
您可以使用类型批注。虽然它不会改变实际的运行时行为,但至少当你尝试覆盖该值时,你的类型检查器会引发错误。Final
from dataclasses import dataclass
from typing import Final
@dataclass(slots=True)
class Pages:
current_page: int # need to be initialized and mutable
last_page: Final[int] # need to be initialized and immutable
first_page: Final[int] = 0 # need to be immutable
评论
Enum
Enum
tuple
enums