Why can't I call the functions within the class?
Question:
I just started Python OOP. I have to build a simple class and function, but I don’t understand why it works in one case, but doesn’t in the other.
class Digital_signal_information:
def __init__(self, signal_power: float, noise_power: float, n_bit_mod: int):
self.signal_power = signal_power
self.noise_power = noise_power
self.n_bit_mod = n_bit_mod
class Line:
def __init__(self,loss_coefficient: float, length: int):
self.loss_coefficient = loss_coefficient
self.length = length
def Loss(self, loss):
self.loss = loss_coefficient * length
BPSK = Digital_signal_information(0.001, 0, 1)
QPSK = Digital_signal_information(0.001, 0, 2) # In these 4 cases it works fine.
Eight_QAM = Digital_signal_information(0.001, 0, 3)
Sixteen_QAM = Digital_signal_information(0.001, 0, 4)
# But if I do
a = Line(1.0, 2);
# and try to call a.Loss, nothing is shown.
In the exercise I have to create the Line
class on which I have to use the signal_power
and length
attributes. I also have to use a function (or property) (correct me if I’m wrong, I’m still getting used to the OOP vocabulary). But as said, I don’t understand why it works in one part, but doesn’t in the other.
Answers:
You can use @property
so that the return value of the function can be directly accessed as a.Loss
.
@property
def Loss(self):
return self.loss_coefficient * self.length
# ...
a = Line(1.0,2)
print(a.Loss) # 2.0
Unmitigated has already found out to use property
. However, if your loss value is not designed to change over time (in other words, the Line
object is designed to be immutable), you can also use functools.cached_property
. This behaves in the same way as property
, but with one difference: it saves the first calculated value and all following times returns the saved one instead of calculating a new one.
The code remains almost the same as Unmitigated‘s code:
from functools import cached_property
class Digital_signal_information:
def __init__(self, signal_power: float, noise_power: float, n_bit_mod: int):
self.signal_power = signal_power
self.noise_power = noise_power
self.n_bit_mod = n_bit_mod
class Line:
def __init__(self, loss_coefficient: float, length: int):
self.loss_coefficient = loss_coefficient
self.length = length
@cached_property
def Loss(self):
return self.loss_coefficient * self.length
BPSK=Digital_signal_information(0.001, 0, 1)
QPSK = Digital_signal_information(0.001, 0, 2) #basically in these 4 cases I have no problem
Eight_QAM = Digital_signal_information(0.001, 0, 3)
Sixteen_QAM = Digital_signal_information(0.001, 0, 4)
#but if I do
a = Line(1.0, 2)
print(a.Loss)
#and when I try to see if I can call a.Loss it shows nothing
You should not use this when the Line
object is intended to change over time. For example, the following code has an incorrect output:
print(a.Loss) # correct
a.length = 3
print(a.Loss) # not correct
Still some final remarks on your code:
- It is better to add spaces around operators and after commas. This makes your code more readable and allows you to change your code easier later on.
- In contrast to many other programming languages, python doesn’t require semicolons (
;
) to seperate lines. It is thus useless to add one.
I just started Python OOP. I have to build a simple class and function, but I don’t understand why it works in one case, but doesn’t in the other.
class Digital_signal_information:
def __init__(self, signal_power: float, noise_power: float, n_bit_mod: int):
self.signal_power = signal_power
self.noise_power = noise_power
self.n_bit_mod = n_bit_mod
class Line:
def __init__(self,loss_coefficient: float, length: int):
self.loss_coefficient = loss_coefficient
self.length = length
def Loss(self, loss):
self.loss = loss_coefficient * length
BPSK = Digital_signal_information(0.001, 0, 1)
QPSK = Digital_signal_information(0.001, 0, 2) # In these 4 cases it works fine.
Eight_QAM = Digital_signal_information(0.001, 0, 3)
Sixteen_QAM = Digital_signal_information(0.001, 0, 4)
# But if I do
a = Line(1.0, 2);
# and try to call a.Loss, nothing is shown.
In the exercise I have to create the Line
class on which I have to use the signal_power
and length
attributes. I also have to use a function (or property) (correct me if I’m wrong, I’m still getting used to the OOP vocabulary). But as said, I don’t understand why it works in one part, but doesn’t in the other.
You can use @property
so that the return value of the function can be directly accessed as a.Loss
.
@property
def Loss(self):
return self.loss_coefficient * self.length
# ...
a = Line(1.0,2)
print(a.Loss) # 2.0
Unmitigated has already found out to use property
. However, if your loss value is not designed to change over time (in other words, the Line
object is designed to be immutable), you can also use functools.cached_property
. This behaves in the same way as property
, but with one difference: it saves the first calculated value and all following times returns the saved one instead of calculating a new one.
The code remains almost the same as Unmitigated‘s code:
from functools import cached_property
class Digital_signal_information:
def __init__(self, signal_power: float, noise_power: float, n_bit_mod: int):
self.signal_power = signal_power
self.noise_power = noise_power
self.n_bit_mod = n_bit_mod
class Line:
def __init__(self, loss_coefficient: float, length: int):
self.loss_coefficient = loss_coefficient
self.length = length
@cached_property
def Loss(self):
return self.loss_coefficient * self.length
BPSK=Digital_signal_information(0.001, 0, 1)
QPSK = Digital_signal_information(0.001, 0, 2) #basically in these 4 cases I have no problem
Eight_QAM = Digital_signal_information(0.001, 0, 3)
Sixteen_QAM = Digital_signal_information(0.001, 0, 4)
#but if I do
a = Line(1.0, 2)
print(a.Loss)
#and when I try to see if I can call a.Loss it shows nothing
You should not use this when the Line
object is intended to change over time. For example, the following code has an incorrect output:
print(a.Loss) # correct
a.length = 3
print(a.Loss) # not correct
Still some final remarks on your code:
- It is better to add spaces around operators and after commas. This makes your code more readable and allows you to change your code easier later on.
- In contrast to many other programming languages, python doesn’t require semicolons (
;
) to seperate lines. It is thus useless to add one.