Python Class 按子类更新父变量
Python Class update parent variables by subclass
由于我对 @property
、@setter
和 @getter
的理解有限,我想出了以下代码。
class BitCounts:
sign_bit = 0
exponent_bits = 0
mantissa_bits = 0
_total_bits = 0
@property
def total_bits(self):
return self._total_bits
@total_bits.setter
def total_bits(self):
self._total_bits = self.sign_bit + self.exponent_bits + self.mantissa_bits
class Single(BitCounts):
sign_bit = 1
offset = 0x7F
exponent_bits = 8
mantissa_bits = 23
_total_bits = BitCounts.total_bits
class Double(BitCounts):
sign_bit = 1
offset = 0x400
exponent_bits = 11
mantissa_bits = 52
_total_bits = BitCounts.total_bits
我的意图是在其他函数中使用子类 Single
和 Double
作为一组选项,例如:
def some_function(option=Single):
print("exponent bit counts are: %d", option.exponent_bits)
print("mantissa bit counts are: %d", option.mantissa_bits)
print("total bit counts are: %d", option.total_bits)
我希望使用子类 Single
或 Double
.
中的值自动重新计算 total_bits
我试图避免额外的函数来执行子类级别的计算。
使用上述代码,通过调用 Single.total_bits
或 Double.total_bits
,我只收到一条消息说 <property object at 0x000002258DF7CB30>
,我做错了什么,我该如何解决?
您使用具有硬编码静态值的子类的方式表明这些应该是实例而不是子类。即使您没有创建任何实例,您也很想使用 self
,这也表明了这一点。 self
指的是特定实例。
此外,setters 通常将值作为参数。您的 setter 中没有它,因为 total_bits 完全依赖于其他值。因此,您应该将 setter 计算移动到 getter 和 return 计算结果。
考虑:
class BitCounts:
def __init__(self, sign,offset, exponent, mantissa):
self.sign_bit = sign
self.offset = offset
self.exponent_bits = exponent
self.mantissa_bits = mantissa
@property
def total_bits(self):
return self.sign_bit + self.exponent_bits + self.mantissa_bits
# now make two instances:
single = BitCounts(1, 0x7F, 8, 23 )
double = BitCounts(1, 0x400, 11, 52)
print(single.total_bits)
# 32
print(double.total_bits)
# 64
您可以使用:
class Single(BitCounts):
sign_bit = 1
offset = 0x7F
exponent_bits = 8
mantissa_bits = 23
_total_bits = BitCounts.total_bits
def get_total_bits(self):
# Update values here, example below
self._total_bits = self._total_bits + 1
return self._total_bits
然后调用:
option = Single()
option.get_total_bits()
这里的问题是您试图从 class.
调用实例方法
class A:
@property
def foo(self):
return 1
print(A.foo) # prints an object of function "foo"
print(A().foo) # prints "1"
要做到这一点,至少据我所知,您需要使用类似于他们在这里所做的元class:
由于我对 @property
、@setter
和 @getter
的理解有限,我想出了以下代码。
class BitCounts:
sign_bit = 0
exponent_bits = 0
mantissa_bits = 0
_total_bits = 0
@property
def total_bits(self):
return self._total_bits
@total_bits.setter
def total_bits(self):
self._total_bits = self.sign_bit + self.exponent_bits + self.mantissa_bits
class Single(BitCounts):
sign_bit = 1
offset = 0x7F
exponent_bits = 8
mantissa_bits = 23
_total_bits = BitCounts.total_bits
class Double(BitCounts):
sign_bit = 1
offset = 0x400
exponent_bits = 11
mantissa_bits = 52
_total_bits = BitCounts.total_bits
我的意图是在其他函数中使用子类 Single
和 Double
作为一组选项,例如:
def some_function(option=Single):
print("exponent bit counts are: %d", option.exponent_bits)
print("mantissa bit counts are: %d", option.mantissa_bits)
print("total bit counts are: %d", option.total_bits)
我希望使用子类 Single
或 Double
.
total_bits
我试图避免额外的函数来执行子类级别的计算。
使用上述代码,通过调用 Single.total_bits
或 Double.total_bits
,我只收到一条消息说 <property object at 0x000002258DF7CB30>
,我做错了什么,我该如何解决?
您使用具有硬编码静态值的子类的方式表明这些应该是实例而不是子类。即使您没有创建任何实例,您也很想使用 self
,这也表明了这一点。 self
指的是特定实例。
此外,setters 通常将值作为参数。您的 setter 中没有它,因为 total_bits 完全依赖于其他值。因此,您应该将 setter 计算移动到 getter 和 return 计算结果。
考虑:
class BitCounts:
def __init__(self, sign,offset, exponent, mantissa):
self.sign_bit = sign
self.offset = offset
self.exponent_bits = exponent
self.mantissa_bits = mantissa
@property
def total_bits(self):
return self.sign_bit + self.exponent_bits + self.mantissa_bits
# now make two instances:
single = BitCounts(1, 0x7F, 8, 23 )
double = BitCounts(1, 0x400, 11, 52)
print(single.total_bits)
# 32
print(double.total_bits)
# 64
您可以使用:
class Single(BitCounts):
sign_bit = 1
offset = 0x7F
exponent_bits = 8
mantissa_bits = 23
_total_bits = BitCounts.total_bits
def get_total_bits(self):
# Update values here, example below
self._total_bits = self._total_bits + 1
return self._total_bits
然后调用:
option = Single()
option.get_total_bits()
这里的问题是您试图从 class.
调用实例方法class A:
@property
def foo(self):
return 1
print(A.foo) # prints an object of function "foo"
print(A().foo) # prints "1"
要做到这一点,至少据我所知,您需要使用类似于他们在这里所做的元class: