第一次尝试使用描述符。你知道吗
目标:0到100(含)之间的任何整数都将是此描述符的合法值。非整数和大于100或小于0的数字应导致引发异常,表明类型和/或值错误。你知道吗
我的代码:
class Percentage():
def __init__(self, initial_value=None):
self.pct_min = 0
self.pct_max = 100
self.value = initial_value
def __get__(self, obj, initial_value):
return self.value
def __set__(self, obj, initial_value):
if self.pct_min <= int(self.value) <= self.pct_max:
return self.value
elif self.value < self.pct_min:
raise ValueError(print("Value to low"))
else:
raise ValueError(print("Value to high"))
class Foo(object):
participation = Percentage()
f1 = Foo()
f1.participation = 30
f2 = Foo()
f2.participation = 70
print(f1.participation) # should print 30
print(f2.participation) # should print 70
对于此行:如果自身百分比最小值<;=整数(自我价值)<;=最大自身百分比地址:
我得到这个错误:
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
我正在通过PythonTutor运行它,看起来我没有传递整数,但是我不明白我在哪里失败了。你知道吗
我也以此为指导:https://www.blog.pythonlibrary.org/2016/06/10/python-201-what-are-descriptors/
这不是描述符本身的问题。问题是,在
__set__
中,不是检查得到的值,而是检查现有的self.value
。因为它被初始化为None
,所以在第一次赋值时总是失败的。你知道吗描述符本身也有一个(不相关的)问题。getter和setter应该从
obj.__dict__
读取/写入,而不是从描述符对象本身读取/写入。否则,所有实例将共享一个公共值这其实不是描述符的问题!您只需将描述符的初始
self.value
属性设置为None
:然后尝试将设置为
None
的self.value
属性值转换为整数:您可能希望将此应用于
initial_value
的__set__
参数!你知道吗您的描述符实现确实还有几个问题:
__set__
返回的任何内容。你知道吗您正在描述符实例本身上存储数据。您的类只有描述符对象的一个副本,所以当您在
Foo()
的不同实例之间使用描述符时,您会看到完全相同的数据。您希望在描述符绑定到的对象上存储数据,因此在__set__
方法中,在obj
上,或者至少在一个允许您将值与obj
关联的地方。obj
是描述符绑定到的Foo()
的特定实例。^{} getter method 不接受“初始值”,它接受要绑定到的对象以及该对象的类型(类)。在类上访问时,
obj
是None
,并且只设置类型。不要混用
print()
和创建异常实例。ValueError(print(...))
没有什么意义,print()
写入控制台,然后返回None
。只需使用ValueError(...)
。我做了以下假设:
那么下面的代码就可以工作了:
演示:
注意,上面使用实例上的特定属性名来设置值。如果在同一个类上有多个描述符实例,这将是一个问题!你知道吗
如果要避免这种情况,您可以选择:
Foo
类示例,将使用Foo
和'participation'
调用它。你知道吗注意,您应该而不是使用属性名(
participation
在Foo
示例中),至少不能直接使用。使用obj.participation
将触发描述符对象本身,因此Percentage.__get__()
或Percencage.__set__()
。但是,对于数据描述符(实现__set__
或__delete__
方法的描述符),可以直接使用vars(obj)
或obj.__dict__
来存储属性。你知道吗相关问题 更多 >
编程相关推荐