i am currently trying to understand some basic concept of Python.
Here is my code :
class BorgSingleton:
_shared_borg_state = {}
test = "toto"
def __init__(self):
self.__dict__ = self._shared_borg_state
print("borg created")
print(self.test)
class Point(BorgSingleton) :
def __init__(self, lat, long):
self.latitude = lat
self.longitude = long
super().__init__()
print (self.latitude)
def g(self) :
return BorgSingleton.test " " str(self.latitude) " " str(self.longitude)
def main():
point_1 = Point(5,2)
point_2 = Point(3,3)
print(point_1.g())
print(point_2.g())
point_1.test = "tata"
print(point_1.g())
print(point_2.g())
if (__name__ == "__main__"):
main()
And here my output :
borg created
toto
Traceback (most recent call last):
File "file1.py", line 32, in
main()
File "file1.py", line 23, in main
point_1 = Point(5,2)
File "file1.py", line 16, in init
print (self.latitude)
AttributeError: 'Point' object has no attribute 'latitude'
I am surely making a basic mistake un python, but i am not sure of why my "Point" don't have a "latitude" attribute here.
I rode about inheritence and Borg conception, but something is missing. I also try the -tt option for indentation mistake.
CodePudding user response:
Try to put super().__init__()
as first instruction in __init__()
method of class Point:
class BorgSingleton:
_shared_borg_state = {}
test = "toto"
def __init__(self):
self.__dict__ = self._shared_borg_state
print("borg created")
print(self.test)
class Point(BorgSingleton):
def __init__(self, lat, long):
super().__init__()
self.latitude = lat
self.longitude = long
#super().__init__()
print(self.latitude)
def g(self):
return BorgSingleton.test " " str(self.latitude) " " str(self.longitude)
def main():
point_1 = Point(5, 2)
point_2 = Point(3, 3)
print(point_1.g())
print(point_2.g())
point_1.test = "tata"
print(point_1.g())
print(point_2.g())
if (__name__ == "__main__"):
main()
CodePudding user response:
The code you've wrote should've worked if self.__dict__
had not been overridden in the parent BorgSingleton
class.
In Python, it is not a good practice to override magic methods (ones that start and end with double-unders) unless you know what you're doing.
To generalize what happened, lets see the below two classes:
class Parent:
some_attribute = {}
def __init__(self):
self.__dict__ = self.some_attribute
class Child(Parent):
def __init__(self, arg_1, arg_2):
self.arg_1 = arg_1
self.arg_2 = arg_2
# at this point, an instance of class Child has arg_1 and arg_2
# attributes, and self.__dict__ stores corresponding values
super().__init__()
# in the Parent class, self.__dict__ is overridden to an empty dict
# which makes arg_1 and arg_2 arguments unaccessible from the
# instance after a super call
test_instance = Child(1, 2)
To make your code work, I suggest you remove self.__dict__
redefinition. Also, on line point_1.test = "tata"
I assume you intended to redefine test
attribute of point_1
instance. However, in Point.g
method you access BorgSingleton.test
attribute, instead of Point.test
attribute, which is available after you call super().__init__()
in Point.__init__
. After all, the below code should work as you've expected:
class BorgSingleton:
_shared_borg_state = {}
test = "toto"
class Point(BorgSingleton):
def __init__(self, lat, long):
self.latitude = lat
self.longitude = long
super().__init__()
def g(self):
return ' '.join((self.test, str(self.latitude), str(self.longitude)))
def main():
point_1 = Point(5, 2)
point_2 = Point(3, 3)
print(point_1.g())
print(point_2.g())
point_1.test = "tata"
print(point_1.g())
print(point_2.g())
if __name__ == "__main__":
main()