Python Forum
Subclass initialized property used in parent class method. Is it bad coding practice?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Subclass initialized property used in parent class method. Is it bad coding practice?
#1
Hello, i have the following code:
class ParentClass:
    def use_name(self):
        print('Using {} somehow'.format(self.name))


class ChildClass(ParentClass):
    def __init__(self, name):
        self.name = name
As you can see i'm using a property created in a subclass, in a method of the parent class which of course works fine only if i run the method from a subclass instance. And i don't intend to instantiate the parent class in any case.
So is it OK or it is still bad coding practice? Is there any improvement on this?
Is it a bad "decoupling" practice since writing code for the parent class i have to know properties of the child class?
Reply
#2
If it were me, I would play it safe by having thenameproperty in the parent class.
class ParentClass:
	def __init__ (self) :
		self.name = None

	def use_name(self):
		if self.name != None :
			print('Using {} somehow'.format(self.name))
menator01 and saavedra29 like this post
Reply
#3
Parent and child are not really the correct terms for a class hierarchy relationship. Use base class, subclass, superclass.

What is your reason for doing such a thing? Maybe you have a good reason. Are you trying to force the subclass to make an instance variable similar to how the abc.abstractmethod forces subclasses to define a method? Unfortunately there is no such thing. In your example the undefined attribute will not be found until it is used.
class ParentClass:
    def use_name(self):
        print('Using {} somehow'.format(self.name))

class ChildClass(ParentClass):
    def __init__(self, name="undefined"):
        self.name = name

class BadChildClass(ParentClass):
    def __init__(self):
        """I don't have a name"""

ChildClass().use_name()
BadChildClass().use_name()
Output:
Using undefined somehow Traceback (most recent call last): File "...", line 14, in <module> BadChildClass().use_name() File "...", line 3, in use_name print('Using {} somehow'.format(self.name)) AttributeError: 'BadChildClass' object has no attribute 'name'
You can have an abstract property, and a property looks and works a lot like an instance variable. In this example ParentClass defines an abstract property name. You still get an error when using BadChildClass, but now the error is identified when the instance is created instead of waiting until you try to use an undefined attribute.
from abc import ABC, abstractmethod

class ParentClass(ABC):
    def use_name(self):
        print('Using {} somehow'.format(self.name))

    @property
    @abstractmethod
    def name(self):
        """Abstract peroperty to get name"""


class ChildClass(ParentClass):
    def __init__(self, name="undefined"):
        self._name = name

    @property
    def name(self):
        return self._name

class BadChildClass(ParentClass):
    def __init__(self):
        """I don't have a name"""

ChildClass().use_name()
BadChildClass().use_name()
Output:
Using undefined somehow Traceback (most recent call last): File "...", line 26, in <module> BadChildClass().use_name() TypeError: Can't instantiate abstract class BadChildClass with abstract method name
saavedra29 likes this post
Reply
#4
@deanhystad i really thought of using the ABC module but first of all it's somehow like turning Python to Java Big Grin . And on the other hand it doesn't solve a problem with giving a more "proper" error when the BadChildClass runs the method. But OK, this is better than before.
OK, my real scenario is that i want a superclass and subclasses for scraping web content. Each subclass has hardcoded the url to scrape. The superclass needs access to this because for every url there is some content that can be scraped in the same exact way so this logic has to be in the superclass. And the rest of the content that is scraped differently in each url will be parsed in the subclass.
So isn't this subclassing model that i use right?
Reply
#5
I would add an __init__(self, url): to the base class and the subclasses should call super().__init__(my_unique_url). Put the things that are common in the base class, and the things that are different in the subclasses. The url is really the same (all subclasses will have a url), but it will have a different value for each instances.

Are the subclasses all singletons?
saavedra29 likes this post
Reply
#6
Oh it was so simple and i didn't think of it. I found the complex way Smile Thanks!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Best practice on using virtual environments in Python bytecrunch 6 644 Feb-14-2024, 03:22 PM
Last Post: snippsat
  super() and order of running method in class inheritance akbarza 7 594 Feb-04-2024, 09:35 AM
Last Post: Gribouillis
  Using one child class method in another child class garynewport 5 1,488 Jan-11-2023, 06:07 PM
Last Post: garynewport
  [Solved] Novice question to OOP: can a method of class A access attributes of class B BigMan 1 1,267 Mar-14-2022, 11:21 PM
Last Post: deanhystad
  dict class override: how access parent values? Andrey 1 1,594 Mar-06-2022, 10:49 PM
Last Post: deanhystad
  class, attribute and method Frankduc 9 2,381 Feb-27-2022, 09:07 PM
Last Post: deanhystad
  Class Method to Calculate Age Doesn't Work gdbengo 1 1,660 Oct-30-2021, 11:20 PM
Last Post: Yoriz
  ABC Module and @property decorator, Pythonic Way? muzikman 21 5,496 Aug-18-2021, 06:08 PM
Last Post: muzikman
  @property vs __set__ / __get__ and __setattr__ / __getattr__ okhajut 1 3,255 Jun-15-2021, 03:48 PM
Last Post: snippsat
  anonymous method in a class Skaperen 8 3,480 May-23-2021, 11:17 PM
Last Post: Skaperen

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020