In one of my classes, I am printing data from another class that is yet to be initialized.I only want to print that data once the class has been initialized.Is there any way check if the class has been instantiated?
Two functions that return true if you pass an undeclared class, and false if it is instantiated:
import inspect
inspect.isclass(myclass)
or
isinstance(myclass, type)
In general, if it's not a type (i.e. undeclared class), it's an instantiated type.
Simply add a variable into the class to be made, like this:
class tobeinitiated():
initiated=False
def __init__(self):
global initiated
tobeinitiated.initiated = True
Then, where you need the information:
global initiated #(if in class)
if tobeinitiated.initiated:
#do the stuff you need to do
Hope this helps. :)
You can add a counter of instances in the constructor for example.
Related
When i use the subclass method, a method that base class don't have, comes the warning.
Code is as following:
class A:
pass
class B(A):
def b_method(self):
pass
def test(arg: A):
arg.b_method() #generate warning at this line
warning:Unresolved attribute reference 'b_method' for class 'A'
The variables of the input function can only be class A and its subclasses, and the function will call the unique method of some subclasses. How to write type annotations to eliminate the warning?
Any help would be greatly appreciated!
The behavior you are seeing is expected.
A is the parent class
B is child class.
B can access a method that A has but not vice versa..
Makes sense?
Want to write to variables in one class, then inherit those set variable values in another class without having set the values again.
Below code should print 100, without having to initialize the values again for subclass instance; want to use the originally set values in master class (data handler).
One class manages all income data; Data Handler, then the other classes simple inherit those values. What is the way of handling this flow structure ? Please and Thank you!!
from dataclasses import dataclass
#dataclass
class Datahandler:
A : int
B : int
C : int
D : int
E : int
F : int
Datahandler=Datahandler(100,100,50,40,10,1000)
class Some_Class(Datahandler):
pass
print(Some_Class.A)
To define an attribute of a class, assign to it in the class definition, not inside any function.
class Datahandler:
staticmember = 200
The dataclass class won't help you with that. It is for defining attributes of class instances, not classes.
You can then access the base class member in a derived class, which is what you want to do.
class Some_Class(Datahandler):
pass
print(Some_Class.staticmember)
Also, you should avoid using the same name for a class and an instance of that class.
Datahandler=Datahandler(100,100,50,40,10,1000) #Likely problematic
Edit: While I answered the question as posted, there are simpler ways to do the same thing without using inheritance, as #juanpa.arrivillaga suggested.
I am currently trying to abstract/default some behaviour away. All children define some constants differently and I want to reference said variable in their parent class. My attempt looks something like this:
class Mother():
a= True
#staticmethod
def something():
return Mother.a
class Child(Mother):
a = False
print(Mother.something())
print(Child.something())
Mother.something() obviously produces True, but Child.something() should produce False.
This doesn't work as I guess in inheritance in Python you don't override the variables but just hides them outside of vision?
In the Child class, when something is called, Mother.a is still valid, you're referring to the parent Mother class (defined at Childs class declaration). Python has another builtin called classmethod for your use case:
class Mother():
a = True
#classmethod
def something(cls):
return cls.a
class Child(Mother): # Mother.a gets defined here
a = False
print(Mother.something()) # True
print(Child.something()) # False
From the docs:
Class methods are different than C++ or Java static methods. If you want those, see staticmethod().
#classmethods define cls (by convention, the variable doesn't have to be called cls) as the first argument, just like instance methods would receive self as their first argument. cls refers to the class that the method is being called on.
I'd recommend this video for a great introduction on best practices for classes and how/where to use all the special decorators/syntax in python.
Since you mentioned abstract classes, you may be interested in the abc module as well.
Let's say I have the following classes:
class Constants():
def __init__(self, constant=None):
self.value = constant
# Some magic goes here
class SomeConstants(Constants):
PROJECT_NAME = 'constants'
How can I make that definition turn programatically into
class SomeConstants(Constants):
#staticmethod
def PROJECT_NAME():
return SomeConstants('constants')
so that whenever I call SomeConstants.PROJECT_NAME, SomeConstants.PROJECT_NAME(), SomeConstants().PROJECT_NAME, or SomeConstants().PROJECT_NAME() I get the same result, namely an instance of ProjectConstants, having 'constants' as its value?
Edit
After John Kugelman's comment, I realize that calling SomeConstants.PROJECT_NAME, and getting an instance of ProjectConstants, having 'constants' as its value would be what I am looking for.
The magic method call() may be what you are looking for here.
The Enum class in Python does what I want.
Using enums, require some slight alterations, but for my intent and purposes, it solves the problem.
If I have the following :
class A:
attrs = [...]
A_attr = [...]
class B(A):
B_attr = [...]
Is there a way to prevent my B subclass from inheriting the A_attr from the A class?
Or would this be considered a bad design and I should better subclass both A and B from a third C class containing all the attrs attributes and add the particular attribute to each subclass like this?
class C:
attrs = [...]
class A(C):
A_attr = [...]
class B(C):
B_attr = [...]
Better idea is to dump the common functionality in a class.
class Commmon:
attrs = [...]
Extend this class who want this extra functonality.
class A(Common):
# only one attribute added in this class
A_attr = [...]
classB(Common):
attrs_B = [...]
Extend class A when that extra attribute is needed in the class, this will bring all those other attributes.
class C(A):
attrs_C = [...]
What this will allow is wherever you want an object of type Common you can provide instance of B as well as C. And wherever you want instance of class A you can provide instance of C. If you add specific instance in each of your subclasses you will not be able to do so.
From Comment
So according to you I should use the second solution I exposed in my question.
No.
Instead of adding the attribute in each subclass, my advice is to add the attribute in a separate class and let your new classes inherit this intermediate class. So you do not have to add the specific attribute in each one of those subclass.
Example is already provided above. Lets see what is the benefit of doing this, as opposed to your suggestion. Take the following function
def foo(obj):
# check to make sure object has the specific attribute
if (isinstance(obj, A)):
pass; #do something
else:
raise TypeError("Object is not an instance of A")
But if we add the specific attribute in each class, the method will need to be changed to something like this:
def foo(obj):
# check to make sure object has the those type which has that specific attribute
if( isinstance(obj, class1) or (isinstance(obj, class2) or ...):
pass; #do something
else:
raise TypeError("Object does not have specific attribute")
Of course, you can perform a check using something like this:
def foo(obj):
# check to make sure obj has attribute
if hasattr(obj, 'property')
pass; # do something
else:
raise TypeError("Object does not have necessary attribute")
Using correct inheritance relationship (as shown in 1st example) will also help your IDE (if you are using one) in inferring types, because IDE can determine which type of object it expects. You can even augment the function with type information like this:
def foo(obj : A):
pass; #do something
That A after colon is a hint to the IDE that function expects an object of type or subtype of A.