Super() class's attributes not inherited? - python-3.x

It seems the child class doesn't inherit the parent attributes, despite calling super().__init__(args).
I read
Python: subclass inherits super class attributes, but loses it's other attributes
and
Subclass is not inheriting the attributes of second Super Class
but I read the attributes should be inherited if called within super().__init__()
With the following code (3.10.1)
class interface(object):
MEDIA = ('COPPER','FIBER')
SPEED_COPPER = ('100', '1G', '2.5G', '5G', '10G')
SPEED_FIBER = ('10G', '25G', '40G', '100G')
TYPE_L2 = ('ACCESS', 'TRUNK', 'HYBRID')
def __init__(self, media = None, speed = None):
self.media = media
self.speed = speed
def set_media(self):
pass
def is_copper(self):
return self.media == 'COPPER'
def is_fiber(self):
return self.media == 'FIBER'
class copper_1G(interface):
def __init__(self):
super().__init__(media = 'COPPER', speed = '1G')
class generic_mod(object):
def __init__(self, max_slots):
self.slots = []
self.max_slots = max_slots
self.set_interfaces()
def set_interfaces(self):
if len(self.slots) < self.max_slots:
for slot in range(0,self.max_slots):
self.slots.append(copper_1G)
class module48_2(generic_mod):
MAX_SLOTS = 48
def __init__(self):
super().__init__(self.MAX_SLOTS)
self.set_interfaces()
>>> ff=module48_2()
>>> ff.slots[0].media
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'copper_1G' has no attribute 'media'
>>> ff.slots[0].speed
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'copper_1G' has no attribute 'speed'
the variable ff.slots[0] doesn't get the attributes media and speed of the parent class, though it gets the methods is_copper, is_fiber, etc etc...

class generic_mod(object):
...
def set_interfaces(self):
if len(self.slots) < self.max_slots:
for slot in range(0,self.max_slots):
self.slots.append(copper_1G)
self.slots.append(copper_1G) -> self.slots.append(copper_1G())

Related

How to access the reference to the head node in this doubly linked list?

reference data types:
class DLLNode:
def __init__(self, val):
self.val = val
self.next = None
self.prev = None
class DLList:
def __init__(self):
self.head = None
self.tail = None
class Solution:
def sortedInsert(self, head, D):
I tried to access the head node's reference but it doesn't seem to work. What is the mistake that I'm doing here?
My Attempt:
class Solution:
def sortedInsert(self, head, D):
itr = head
while itr:
print(itr.val)
itr = itr.next
return head
The error:
Traceback (most recent call last):
File "main.py", line 107, in <module>
retval = Solution().sortedInsert( head, D )
File "main.py", line 86, in sortedInsert
print(itr.val)
AttributeError: 'DLList' object has no attribute 'val'

python3 - child class does not inherit parent method when parent is in a separate file

In Python3.7.4 my child class is not inheriting a method from its parent when they are in separate files. Here are file snippets...
linkedlist.py
class Node(object):
def __init__(self, data):
self.data = data
self.next_node = None
class LinkedList(object):
def __init__(self):
self.header = None
def print_list(self):
# print data in each node
lifo_queue.py
from linked_list import *
class Lifo(LinkedList):
# definitions for pop() and push()
test.py
from lifo_queue import Lifo
myList = Lifo()
myList.push("abc")
myList.push("def")
myList.push("ghi")
myList.print_list()
running the program test.py returns an error, referring to the statement myList.print_list():
Traceback (most recent call last):
File "test.py", line 7, in <module>
myList.print_list()
AttributeError: 'Lifo' object has no attribute 'print_list'
I've seen similar patterns work in the past, but don't see what I'm doing wrong here. test.py runs okay if class definitions for Lifo and LinkedList are in the same file.
Isn't it the name incorrect in the file where you are importing it.
In lifo_queue.py
from linked_list import *
But you have file name as
linkedlist.py

How to build a class-based decorator of a class in Python?

class Taggable:
TAG_ATTR_NAME = "_taggable_tag"
#staticmethod
def GetTag(target) -> str:
if not hasattr(target,Taggable.TAG_ATTR_NAME):
raise Exception(f"Object is not tagged")
return getattr(target,Taggable.TAG_ATTR_NAME)
def __init__(self, tag :str = "default_tag"):
self.tag = tag
def __call__(self,cls :type):
orig_new = cls.__new__
def my_new():
instance = orig_new(cls)
setattr(instance, Taggable.TAG_ATTR_NAME, self.tag)
return instance
if not isinstance(cls,type):
raise Exception(f"Decorator {type(self).__name__} applied to value {repr(cls)} of type {type(cls).__name__}")
cls.__new__ = my_new()
return cls
#Taggable
class A:
def __init__(self,fa :str):
self.fa = fa
print(f"__init__ called on A with fa={self.fa}, tagged as {Taggable.GetTag(self)}")
class B(A):
def __init__(self, fa: str, fb: str):
super().__init__(fa)
self.fb = fb
print(f"__init__ called on B with fb={self.fb}")
b: B = B("aaa","bbb")
print(Taggable.GetTag(b))
Running this on python 3.6 gives me the following error:
Traceback (most recent call last):
File "/Users/$user/Library/Preferences/PyCharmCE2019.1/scratches/scratch.py", line 35, in <module>
class B(A):
TypeError: __init__() takes from 1 to 2 positional arguments but 4 were given
Looking around the web there seems to be little to no authoritative documentation on how class decorator classes are initialized and called by the interpreter and what arguments are passed to their dunder methods

TypeError: super() argument 1 must be type, not str in Python3.7

When I try to call the constructor of the superclass in the constructor of thermo.py (files below), I get the following error:
Traceback (most recent call last):
File "/var/wheaterstation/scripts/wsControl.py", line 58, in <module>
controller = controller()
File "/var/wheaterstation/scripts/wsControl.py", line 21, in __init__
self.thermo = thermo("Thermometer", logger)
File "/var/wheaterstation/scripts/thermo.py", line 7, in __init__
super(name, logger).__init__()
TypeError: super() argument 1 must be type, not str
Ive seen that in 2.6 this error often would come up if the supperclass wouldn't extend "object". I tried this but it doesn't seem to work.
wsPart.py:
class wsPart(object):
logger = None
name = ""
def __init__(self, name, logger):
self.logger = logger
self.name = name
self.logger.writeLog(self, "created")
def getName(self):
return self.name
thermo.py:
import os, sys
from wsPart import wsPart
class thermo:
functional = False
file = '/sys/bus/w1/devices/28-00000833e8ff/w1_slave'
def __init__(self, name, logger):
super(name, logger).__init__() ## this calls the wsPart constructor
functional = True
def read(self):
##reads out the file mentioned in line 5 and returns it
fileobject = open(self.file)
filecontent = fileobject.read()
fileobject.close()
self.logger.writeLog(self,"Completed Meassurement")
return filecontent
and the part of wsControl.py that matters:
class controller():
name = ""
logger = None
thermo = None
dbConnector = None
def __init__(self):
##THis created the controller and all the other objects
self.name = "Controller"
##Create Objects
self.logger = logger()
self.logger.writeLog(self, "logger created")
self.thermo = thermo("Thermometer", logger)
self.dbConnector = dbConnector("DBConnector",logger)
the full code is here
I first had to make thermo to be a subclass of wsPart:
class thermo:
changed to
class thermo(wsPart):
Then had to change:
super(name, logger).__init__()
to:
super().__init__(name, logger)

AttributeError when monkey patching an object in python

I tried to monkey patch an object in Python.
class C:
def __init__(self):
self.__n = 0
def f(self):
self.__n += 1
def __str__(self):
return str(self.__n)
c = C()
def up(self):
self.__n += 2
import types
c.up = types.MethodType(up, c)
c.up()
But I got an AttributeError
Traceback (most recent call last):
File "untitled4.py", line 19, in <module>
c.up()
File "untitled4.py", line 15, in up
self.__n += 2
AttributeError: 'C' object has no attribute '__n'
How can I fix the error?
As your up function isn't declared inside a class, it is not possible to apply name mangling rules to its locals, while it is applied for the attribute name. Therefore you'd need to apply the name mangling manually in your function:
def up(self):
self._C__n += 2

Resources