With my limited understanding of @property
,@setter
, and @getter
, I came up with following code.
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
My intention is to use the subclass Single
and Double
in other functions as a set of options like so, for example:
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)
I would like total_bits
to be automatically recalculated using values from subclass Single
or Double
.
I am trying to avoid extra functions to perform the calculation at subclass level.
With above codes, by calling Single.total_bits
, or Double.total_bits
, I am only getting a message saying <property object at 0x000002258DF7CB30>
, what did I do wrong, and how can I fix it?
CodePudding user response:
The way you are using subclasses with hard-coded static values suggests these should be instances not subclasses. This is also suggested by your temptation to use self
even though you haven't made any instances. self
refers to a particular instance.
Also, setters typically take a value as an argument. You don't have that in your setter because total_bits is completely dependent on other values. As such you should just move your setter calculation to the getter and return the result of the calculation.
Consider:
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
CodePudding user response:
You can use:
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
Then call:
option = Single()
option.get_total_bits()
CodePudding user response:
The problem here is that you are trying to call an instance method from a class.
class A:
@property
def foo(self):
return 1
print(A.foo) # prints an object of function "foo"
print(A().foo) # prints "1"
To accomplish this, at least from my knowledge you need to use a metaclass similar to what they do here: Per-class @property decorator in Python