- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在尝试将数据类与属性一起使用时遇到了一个奇怪的问题。
我已经把它缩小到了重现它的最低限度:
import dataclasses
@dataclasses.dataclass
class FileObject:
_uploaded_by: str = dataclasses.field(default=None, init=False)
uploaded_by: str = None
def save(self):
print(self.uploaded_by)
@property
def uploaded_by(self):
return self._uploaded_by
@uploaded_by.setter
def uploaded_by(self, uploaded_by):
print('Setter Called with Value ', uploaded_by)
self._uploaded_by = uploaded_by
p = FileObject()
p.save()
输出:
Setter Called with Value <property object at 0x7faeb00150b0>
<property object at 0x7faeb00150b0>
我希望得到 None 而不是
我在这里做错了什么或者我偶然发现了一个错误吗?
阅读@juanpa.arrivilillaga的答案后,我认为制作uploaded_by和InitVar可能会解决问题,但它仍然返回一个属性对象。我想是因为他说的是这样的:
the datalcass machinery interprets any assignment to a type-annotated variable in the class body as the default value to the created
__init__
.
我能找到的使用默认值的唯一选项是从数据类定义中删除 uploadedby 并编写实际的 __init__
。这有一个不幸的副作用,即要求您手动为数据类编写 __init__
,这否定了使用数据类的一些值(value)。这是我所做的:
import dataclasses
@dataclasses.dataclass
class FileObject:
_uploaded_by: str = dataclasses.field(default=None, init=False)
uploaded_by: dataclasses.InitVar=None
other_attrs: str = None
def __init__(self, uploaded_by=None, other_attrs=None):
self._uploaded_by = uploaded_by
self.other_attrs = other_attrs
def save(self):
print("Uploaded by: ", self.uploaded_by)
print("Other Attrs: ", self.other_attrs)
@property
def uploaded_by(self):
if not self._uploaded_by:
print("Doing expensive logic that should not be repeated")
return self._uploaded_by
p = FileObject(other_attrs="More Data")
p.save()
p2 = FileObject(uploaded_by='Already Computed', other_attrs="More Data")
p2.save()
哪些输出:
Doing expensive logic that should not be repeated
Uploaded by: None
Other Attrs: More Data
Uploaded by: Already Computed
Other Attrs: More Data
这样做的负面影响:
__init__
(我的实际用例大约有20 个属性)__repr__
中丢失了 uploaded_by,但它仍然存在在_uploaded_by所以这确实不能解决问题
我已在 Python Bug Tracker 上提交了一个 Bug: https://bugs.python.org/issue39247
最佳答案
因此,不幸的是,@property
语法始终被解释为对 uploaded_by
的赋值(因为,嗯,它是)。 dataclass
机制将其解释为默认值,因此它传递属性对象!它相当于:
In [11]: import dataclasses
...:
...: @dataclasses.dataclass
...: class FileObject:
...: uploaded_by: str
...: _uploaded_by: str = dataclasses.field(repr=False, init=False)
...: def save(self):
...: print(self.uploaded_by)
...:
...: def _get_uploaded_by(self):
...: return self._uploaded_by
...:
...: def _set_uploaded_by(self, uploaded_by):
...: print('Setter Called with Value ', uploaded_by)
...: self._uploaded_by = uploaded_by
...: uploaded_by = property(_get_uploaded_by, _set_uploaded_by)
...: p = FileObject()
...: p.save()
Setter Called with Value <property object at 0x10761e7d0>
<property object at 0x10761e7d0>
本质上是这样的:
In [13]: @dataclasses.dataclass
...: class Foo:
...: bar:int = 1
...: bar = 2
...:
In [14]: Foo()
Out[14]: Foo(bar=2)
我认为没有一个干净的方法来解决这个问题,也许它可以被认为是一个错误,但实际上,不确定解决方案应该是什么,因为本质上,datalcas 机制解释对类型注释的任何分配类体中的变量作为创建的__init__
的默认值。您也许可以对 @property
语法进行特殊处理,或者只是 property
对象本身,因此至少 @property
和x = property(set_x, get_x)
是一致的...
需要明确的是,以下作品:
In [22]: import dataclasses
...:
...: @dataclasses.dataclass
...: class FileObject:
...: uploaded_by: str
...: _uploaded_by: str = dataclasses.field(repr=False, init=False)
...: @property
...: def uploaded_by(self):
...: return self._uploaded_by
...: @uploaded_by.setter
...: def uploaded_by(self, uploaded_by):
...: print('Setter Called with Value ', uploaded_by)
...: self._uploaded_by = uploaded_by
...:
...: p = FileObject(None)
...: print(p.uploaded_by)
Setter Called with Value None
None
In [23]: FileObject()
Setter Called with Value <property object at 0x1086debf0>
Out[23]: FileObject(uploaded_by=<property object at 0x1086debf0>)
但请注意,您无法设置有用的默认值!它总是会占用该属性...更糟糕的是,IMO,如果您不想要默认值,它总是会创建一个!
这应该是显而易见的,但您可以只在类上设置属性对象。
import dataclasses
import typing
@dataclasses.dataclass
class FileObject:
uploaded_by:typing.Optional[str]=None
def _uploaded_by_getter(self):
return self._uploaded_by
def _uploaded_by_setter(self, uploaded_by):
print('Setter Called with Value ', uploaded_by)
self._uploaded_by = uploaded_by
FileObject.uploaded_by = property(
FileObject._uploaded_by_getter,
FileObject._uploaded_by_setter
)
p = FileObject()
print(p)
print(p.uploaded_by)
关于python - 一起使用数据类和属性时出现奇怪的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59623952/
我的应用程序从一个有 5 个选项卡的选项卡栏 Controller 开始。一开始,第一个出现了它的名字,但其他四个没有名字,直到我点击它们。然后根据用户使用的语言显示名称。如何在选项卡栏出现之前设置选
我有嵌套数组 json 对象(第 1 层、第 2 层和第 3 层)。我的问题是数据表没有出现。任何相关的 CDN 均已导入。该表仅显示部分。我引用了很多网站,但都没有解决我的问题。 之前我使用标准表来
我正在尝试设置要显示的 Parse PFLoginViewController。这是我的一个 View Controller 的类。 import UIKit import Parse import
我遇到了这个问题,我绘制的对象没有出现在 GUI 中。我知道它正在被处理,因为数据被推送到日志文件。但是,图形没有出现。 这是我的一些代码: public static void main(Strin
我有一个树状图,其中包含出现这样的词...... TreeMap occurrence = new TreeMap (); 字符串 = 单词 整数 = 出现次数。 我如何获得最大出现次数 - 整数,
因此,我提示用户输入变量。如果变量小于 0 且大于 10。如果用户输入 10,我想要求用户再次输入数字。我问时间的时候输入4,它说你输入错误。但在第二次尝试时效果很好。例如:如果我输入 25,它会打印
我已经用 css overflow 属性做了一个例子。在这个例子中我遇到了一个溢出滚动的问题。滚动条出现了,但没有工作意味着每当将光标移动到滚动条时,在这个滚动条不活动的时间。我对此一无所知,所以请帮
我现在正在做一个元素。当您单击一个元素时,会出现以下信息,我想知道如何在您单击下一个元素而不重新单击同一元素时使其消失....例如,我的元素中有披萨,我想单击肉披萨看到浇头然后点击奶酪披萨看到浇头和肉
我有一个路由器模块,它将主题与正则表达式进行比较,并将出现的事件与一致的键掩码链接起来。 (它是一个简单的 url 路由过滤,如 symfony http://symfony.com/doc/curr
这个问题在这里已经有了答案: 9年前关闭。 Possible Duplicate: mysql_fetch_array() expects parameter 1 to be resource, bo
我在底部有一个带有工具栏的 View ,我正在使用 NavigationLink 导航到该 View 。但是当 View 出现时,工具栏显示得有点太低了。大约半秒钟后,它突然跳到位。它只会在应用程序启
我试图在我的应用程序上为背景音乐添加一个 AVAudioPlayer,我正在主屏幕上启动播放器,尝试在应用程序打开时开始播放但出现意外行为... 它播放并立即不断创建新玩家并播放这些玩家,因此同时播放
这是获取一个数字,获取其阶乘并将其加倍,但是由于基本情况,如果您输入 0,它会给出 2 作为答案,因此为了绕过它,我使用了 if 语句,但收到错误输入“if”时解析错误。如果你们能提供帮助,我真的很感
暂停期间抛出异常 android.os.DeadObjectException 在 android.os.BinderProxy.transactNative( native 方法) 在 androi
我已经为猜词游戏编写了一些代码。它从用户输入中读取字符并在单词中搜索该字符;根据字符是否在单词中,程序返回并控制一些变量。 代码如下: import java.util.Random; import
我是自动化领域的新手。这是我的简单 TestNG 登录代码,当我以 TestNG 身份运行该代码时,它会出现 java.lang.NullPointerException,双击它会突出显示我导航到 U
我是c#程序员,我习惯了c#的封装语法和其他东西。但是现在,由于某些原因,我应该用java写一些东西,我现在正在练习java一天!我要创建一个为我自己创建一个虚拟项目,以便让自己更熟悉 Java 的
我正在使用 Intellij,我的源类是 main.com.coding,我的资源文件是 main.com.testing。我将 spring.xml 文件放入资源文件中。 我的测试类位于 test.
我想要我的tests folder separate到我的应用程序代码。我的项目结构是这样的 myproject/ myproject/ myproject.py moduleon
这个问题已经有答案了: What is a NullPointerException, and how do I fix it? (12 个回答) 已关闭 6 年前。 因此,我尝试比较 2 个值,一个
我是一名优秀的程序员,十分优秀!