Error trying to access a parent variable from his child class - python-3.x

So I have this class:
class UniversalHash(HashClass):
##################################################
def __init__(self):
super().__init__()
self.__MParamK = int(0)
self.__MParamC = int(0)
self.__MParamD = int(0)
# Override #
def FindHash(self, Key):
return (((self.__MParamK * Key) + self.__MParamC) % self.__MParamD) % self.__MParamL
def SetParamK(self, Value):
self.__MParamK = Value
def SetParamC(self, Value):
self.__MParamC = Value
def SetParamD(self, Value):
self.__MParamD = Value
And the parent class:
class HashClass:
##################################################
def __init__(self):
self.__MParamL = int(0)
def SetParamL(self, Value):
self.__MParamL = Value
def GetParamL(self):
return self.__MParamL
def FindHash(self, Key):
pass
When I try to access to the variable __MParamL (the variable created in the parent), it gives me an exception telling me that the variable is not an attribute of this class, I have searched on the web and it seems this is the correct way to write the code (maybe the overridden function is the problem?). Any help is appreciated

When you name an instance attribute with a leading double underscore, it will get name mangled, E.g.,
>>> class A:
... def __init__(self):
... self.x = 42
... self.__y = 42
...
>>> a = A()
>>> vars(a)
{'x': 42, '_A__y': 42}
Instead, you should just use a single underscore, E.g.,
>>> class A:
... def __init__(self):
... self.x = 42
... self._y = 42
...
>>> a = A()
>>> vars(a)
{'x': 42, '_y': 42}

Related

【python】why parent variables address is the same in the child class object

The following is my python code. I think output_ports and input_ports have diffrent address.
class test():
def __init__(self) -> None:
pass
class INode(object):
node_name = "INode"
config = None
output_ports = []
input_ports = []
def __init__(self) -> None:
super().__init__()
pass
def NodeStart(slef):
pass
def GetOutputPort(self):
print(self)
index = len(self.output_ports)
# self.output_ports[index] = test()
self.output_ports.append(test())
# return self.output_ports[index]
def GetInputPort(self):
print(self)
index = len(self.output_ports)
self.input_ports.append(test())
class AdbCollectNode(INode):
def __init__(self) -> None:
super(AdbCollectNode, self).__init__()
self.node_name = "s"
pass
def LinkNode(node_output, node_input):
node_output.GetOutputPort()
node_input.GetInputPort()
if __name__ == '__main__':
adb_node = AdbCollectNode()
adb_node_1 = AdbCollectNode()
adb_node_2 = AdbCollectNode()
LinkNode(adb_node_1, adb_node_2)
LinkNode(adb_node_1, adb_node)
print(id(adb_node_1.input_ports))
print(id(adb_node.input_ports))
print(id(adb_node_2.input_ports))
print(id(adb_node_1.output_ports))
print(id(adb_node.output_ports))
print(id(adb_node_2.output_ports))
id() output as follow:
4549382592
4549382592
4549382592
4549356224
4549356224
4549356224
I think the subclass variables address are the same。 why not same?

Property created with #property performs differently

>>> class test():
name = 'tiger'
def __init__(self,value):
self.name = value
>>> class subtest(test): pass
>>> a = subtest('cat')
>>> super(subtest,subtest).name
'tiger'
When I use super(class, class) to access a normal property of class, it gets value of that property. However, when I rewrite that property with #property, it turns out to a property object, why and what happend?
>>> class test():
name = 'tiger'
def __init__(self,value):
self._name = value
#property
def name(self):
return self._name
#name.setter
def name(self,value):
self._name = value
>>> class subtest(test): pass
>>> super(subtest,subtest).name
<property object at 0x03AB6300>

Python: creating a dictionary: {int, class object} in a loop

I'd like to create a dictonary: {int, Class} in a loop, however the class object is being overriden.
I am pretty sure that this is a basic problem, but I am stuck
class Simple:
simpleDic = {
'name': {""},
'age': {1}}
def __init__(self, name, age):
self.simpleDic['name'] = name
self.simpleDic['age'] = age
def __str__(self):
return "{} {}\n".format(self.simpleDic['name'], self.simpleDic['age'])
def foo():
myDict = {}
for x in range(3):
myDict[x] = Simple('Name' + str(x), x)
print(('{}: {}\n'.format("Creating", myDict[x])))
for key in myDict:
print(('{}: {}\n'.format("Printing" + str(key), myDict[key])))
#### Main program here ####
foo()
The output is as follows:
You're problem is on the last print
You're printing myDict[x] when you should print myDict[key]
x contains the last value from the first iteration, so you're practically printing the same key all over
Following your question in this comments:
class Simple:
def __init__(self, name, age):
self.simpleDic = {"name": name, "age": age}
def __str__(self):
return "{} {}\n".format(self.simpleDic['name'], self.simpleDic['age'])
def __repr__(self):
return "{} {}\n".format(self.simpleDic['name'], self.simpleDic['age'])
def foo():
myDict = {}
for x in range(3):
myDict[x] = Simple('Name' + str(x), x)
print(('{}: {}\n'.format("Creating", myDict[x])))
print(myDict)

how can i iterate class objects while using generator in python?

i want to compare the 2000 pairs of a and b, and print the matching pairs and count of them.can anyone help me to get rid of it.it shows this error TypeError: 'seq_generator' object is not iterable at line 34
class generator(object):
def __init__(self,s,start_A,fact_A):
self.s=s
self.start_A=start_A
self.fact_A = fact_A
def seq_gen_A(self):
while self.s>0:
self.gen_A=(self.start_A*self.fact_A)%2147483647
self.g=self.gen_A
self.start_A=self.gen_A
self.bin_A=(bin(self.gen_A)[-16:])
yield self.bin_A
self.s=self.s-1
def next(self):
for i in self.seq_gen_A():
return i
def main():
s=200
count=0
a=generator(s,65,16807)
b=generator(s,8921,48271)
print("Matching pair")
print("*************")
for i in range(0,s):
if next(a)==next(b):
count+=1
print(a,b)
print('Matching pair count',count)
You are defining your generator not correctly. You need methods __iter__ and __next__:
class generator(object):
def __init__(self, s, start_A, fact_A):
self.s = s
self.start_A = start_A
self.fact_A = fact_A
def __iter__(self):
return self
def __next__(self):
if self.s <= 0:
raise StopIteration()
gen_A = (self.start_A*self.fact_A)%2147483647
self.start_A = gen_A
yield bin(gen_A)[-16:]
self.s -= 1

I can't figure out what's wrong with the python code below. It keeps giving me Attribute error: 'Dog' object has no attribute '_Dog_name'

class Animal:
__name = None
__height = 0
__weight = 0
__sound = 0
We call a constructor, a constructor is called to setup/initialize an object
def __init__(self, name, height, weight, sound):
self.__name = name
self.__height = height
self.__weight = weight
self.__sound = sound
def set_name(self, name):
self.__name = name
def get_name(self):
return self.__name
def set_height(self, height):
self.__height = height
def get_height(self, height):
return self.__height
def set_weight(self, weight):
self.__weight = weight
def get_weight(self):
return self.__weight
def set_sound(self, sound):
self.__sound = sound
def get_sound(self):
return self.__sound
def get_type(self):
print("Animal")
def toString(self):
return "{} is {} cm tall and {} kilograms in weight and makes the sound {}".format(self.__name, self.__height,
self.__weight, self.__sound)
cat = Animal('Whiskers', 33, 20, 'meow')
print(cat.get_name())
print(cat.toString())
class Dog(Animal):
__owner= ""
def __init__(self,name,height,weight,sound,owner):
self.__owner=owner
super(Dog,self).__init__(name,height,weight,sound)
def set_owner(self,owner):
self.__owner=owner
def get_owner(self):
return self.__owner
def get_type(self):
print("dog")
def toString(self):
return"{} is {} cm tall and weighs {}. He says {} and his owner is {}".format(self.__name,
self.__height,
self.__weight,
self.__sound,
self.__owner)
Spot = Dog("Spot",45,77,"Ruff","Amit")
print(Spot.toString())
Here the class Animal is being called in to use its attributes. I saw this on a tutorial video, it seems to be running fine in the video but not when I try it
The issue is with "name mangling" (c.f. https://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references). If you wish to access super class variables with double underscores, you should prefix them with the class name:
def toString(self):
return"{} is {} cm tall and weighs {}. He says {} and his owner is {}".\
format(self._Animal__name,
self._Animal__height,
self._Animal__weight,
self._Animal__sound,
self.__owner)
Alternatively you could call the getters from Animal such as self.get_name().

Resources