【python】why parent variables address is the same in the child class object - python-3.x

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?

Related

Python class instant handling

Suppose we have a class called Operation that does some operation with new information coming in. As a former Matlab user, I am used to handle and value class types.
Option 1: update directly (i.e., using the same class instant)
class Operation:
def __init__(self):
self.some_internal_data = []
self._result = []
def step(self, info):
[operation using self and info]
self._result = ...
#property
def result(self):
return self._result
oper = Operation()
while True:
info = get_new_info()
oper.step(info)
print(oper.result)
Option 2: return new instant up on step method
class Operation:
def __init__(self):
self.some_internal_data = []
self._result = []
def __copy__(self):
...
def step(self, info):
obj = self.copy()
[operation using obj and info]
return obj
#property
def result(self):
return self._result
oper = Operation()
while True:
info = get_new_info()
oper = oper.step(info)
print(oper.result)
I have been using Option 2 most of the time. This is because I have been thinking that Option 1 is more for storing information whilst Option 2 is keeping track of states.
What is the most Pythonic practice?

Error trying to access a parent variable from his child class

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}

I want to write using the 'shelve' module, but after entering 3 data, I can't enter anymore and the keys in the file are stored incorrectly

I want to write using the 'shelve' module, but after entering 3 data, I can't enter anymore and the keys in the file are stored incorrectly ['3', '1', '2']. that's what happens on linux, and it's all good on windows
class BasicModel(ABC):
table = '.db'
def __init__(self):
self.id = None
self.created_date = None
self.updated_date = None
self.isValid = True
def save(self):
if self.isValid:
path = getAbsolutePath(self.table)
with shelve.open(path, writeback=True) as db:
# Shu obj yangi yaratilayotgani
if self.id is None:
self.created_date = datetime.now()
if list(db.keys()):
print(list(db.keys()))
self.id = int(list(db.keys())[-1]) + 1
else:
self.id = '1'
else:
self.updated_date = datetime.now()
db[str(self.id)] = self
else:
raise ValueError("Qiymatlardan biri noto'g'iri")
def delete(self):
with shelve.open(getAbsolutePath(self.table)) as db:
del db[str(self.id)]
def objects(table: str):
with shelve.open(getAbsolutePath(table)) as db:
for obj in db.values():
yield obj
#property
def isValid(self):
return self.__isValid
#isValid.setter
def isValid(self, value):
self.__isValid = value
class Brand(BasicModel):
table = 'Brands'
def __init__(self, name):
super().__init__()
self.name = name

How to define and use a funciton outside a class?

In the following code for linked list implementation in Python3. How do I define and call the functions such as reverse() and display() outside of the class. Like, how should create a function that performs operations like display() and recerse(). How should I pass a LinkedList object and how to access its members, so that I am able to do desired operations?
PS : I removed other functions because I was not able to post this question.
I am not asking about importing the class file to use in other .py files.
class Node:
def __init__(self,data):
self.data = data
self.next = None
class LinkedList:
def __init__(self):
self.head = None
def display(self):
curr = self.head
while curr != None:
print(curr.data + '->', end = ' ')
curr = curr.next
print('NULL')
def append(self, data):
'''
statements....
'''
def length(self):
ptr = self.head
count = 0
while ptr.next != None:
count += 1
ptr = ptr.next
print(count+1)
def reverse(self):
pre = None
cur = self.head
while cur != None:
temp = cur.next
cur.next = pre
pre = cur
cur = temp
self.head = pre
self.display()
l = LinkedList()
l.append('A')
l.append('B')
l.append('C')
l.append('D')
l.prepend('E')
l.display()
not sure I'm understanding your question correctly, but if I am it seems that you just want to take all of the code, minus the program code (from "l=LinkedList()" down in your example), and save it to a python file, then at the top of any python code you need to use your class in, import your file.
If your class file is not in the same directory as the code from which you wish to use the class, you'll need to keep the class file in a directory in your path:
import sys
print(sys.path)
and if you wish to add a directory to your path, you can:
sys.path.append('<directory')
At that point, once you
import LinkedList
(assuming your class file is called LinkedList.py) you'll be able to define variables using your class and use it the same as you would in your example, so your code file would look something like:
import LinkedList
l = LinkedList()
l.append('A')
l.append('B')
l.append('C')
l.append('D')
l.prepend('E')
l.display()
Or am I just not reading your question correctly?
I added the prepend and append method for you, I'm not sure if this is what you were referring to. Also, if you're looking for static vs class methods, you can check those out here: Class method vs static method in Python
With static methods you can return instances of a specified class by using arguments to the static method. Check out the link above to use class functions outside of their instances.
Here is the Python code:
class Node:
def __init__(self,data):
self.data = data
self.next = None
class LinkedList:
def __init__(self):
self.head = None
def display(self):
curr = self.head
while curr != None:
print(curr.data + '->', end = ' ')
curr = curr.next
print('NULL')
def append(self, data):
data_node = Node(data)
data_node.next = self.head
self.head = data_node
def prepend(self, data):
ptr = self.head
while ptr.next != None:
ptr = ptr.next
ptr.next = Node(data)
def length(self):
ptr = self.head
count = 0
while ptr.next != None:
count += 1
ptr = ptr.next
print(count+1)
def reverse(self):
pre = None
cur = self.head
while cur != None:
temp = cur.next
cur.next = pre
pre = cur
cur = temp
self.head = pre
self.display()
l = LinkedList()
l.append('A')
l.append('B')
l.append('C')
l.append('D')
l.prepend('E')
l.display()

TypeError: A_class_meth() missing 1 required positional argument: 'A_class_meth_var1'

I'm getting the following error for my code:
TypeError: A_class_meth() missing 1 required positional argument: 'A_class_meth_var1'.
What should be modify in "A.A_class_meth"?
class A():
def __init__(self,init_var):
self.init_var = init_var
def A_class_meth(self, A_class_meth_var1):
print("run")
class B():
def Start(self):
self.B_class_var = A("NAME")
A.A_class_meth(self.B_class_var)
var = B()
var.Start()
Create and store an instance of your A class inside the start() method and then reference that.
Otherwise, the self.B_class_var is getting passed as the self parameter
class A():
def __init__(self,init_var):
self.init_var = init_var
def A_class_meth(self, A_class_meth_var1):
print("run")
class B():
def start(self):
a = A("NAME")
self.B_class_var = a
a.A_class_meth(self.B_class_var)
var = B()
var.start()
>> run
or else, alternatively, as suggested above, make the A_class_meth a static method and remove the self parameter:
class A():
def __init__(self,init_var):
self.init_var = init_var
#staticmethod
def A_class_meth(A_class_meth_var1):
print("run")
class B():
def start(self):
self.B_class_var = A("NAME")
A.A_class_meth(self.B_class_var)
var = B()
var.start()
>> run

Resources