Sharing data between classes without objects - python

I have an issue with sharing data between classes. I guess how it works with objects, but I need to share data without creating objects, for example:
class First_class:
def __init__(self):
var = 1 ##create some random variable
class Second_class:
def on_click(self):
print(var) ##working with variable from First_class
First_class()
Second_class()
Some ideas on how to make it or some better solution? btw I use Tkinter and these classes simulate frames with some widgets, so more specifics:
class Frame1:
def __init__(self):
name = Enter(root)
class Frame2:
def on_click(self):
print(name.get())
Frame1()
Frame2()

Set the variable as a class property instead of under init, as the class would have to be initialised in order to get that value.
class First_class:
var = 1
def __init__(self):
pass
class Second_class:
def on_click(self):
print(First_class.var)

Related

Choosing between base class or extended class - Python

I have a Python library which will be used by other people:
class BaseClassA:
class BaseClassB:
def func0(self):
this.class_a_obj = BaseClassA()
BaseClassB creates a BaseClassA object and stores a pointer. This is an issue because I want to allow the user to extend my library classes:
class ExtendClassA(BaseClassA):
And my library should choose the extended class (ExtendClassA) instead of the base class (BaseClassA) in the func0 method.
Above is a very simple example my problem statement. In reality I have 10ish classes where extending/creation happens. I want to avoid the user having to rewrite func0 in an extended BaseClassB to support the new ExtendClassA class they created.
I'm reaching out to the stack overflow community to see what solutions other people have implemented for issues like this. My initial thought is to have a global dict which 'registers' class types/constructors and classes would get the class constructors from the global dict. When a user wants to extend a class they would replace the class in the dict with the new class.
Library code:
global lib_class_dict
lib_class_dict['ClassA'] = BaseClassA()
lib_class_dict['ClassB'] = BaseClassB()
class BaseClassA:
class BaseClassB:
def func0(self):
this.class_a_obj = lib_class_dict['ClassB']
User code:
lib_class_dict['ClassA'] = ExtendClassA():
class ExtendClassA:
EDIT: Adding more details regarding the complexities I'm dealing with.
I have scenarios where method calls are buried deep within the library, which makes it hard to pass a class from the user entry point -> function:
(user would call BaseClassB.func0() in below example)
class BaseClassA:
class BaseClassB:
def func0(self):
this.class_c_obj = BaseClassC()
class BaseClassC:
def __init__(self):
this.class_d_obj = BaseClassD()
class BaseClassD:
def __init__(self):
this.class_a_obj = BaseClassA()
Multiple classes can create one type of object:
class BaseClassA:
class BaseClassB:
def func0(self):
this.class_a_obj = BaseClassA()
class BaseClassC:
def __init__(self):
this.class_a_obj = BaseClassA()
class BaseClassD:
def __init__(self):
this.class_a_obj = BaseClassA()
For these reasons I'm hoping to have a global or central location all classes can grab the correct class.
Allow them to specify the class to use as an optional parameter to func0
def BaseClassB:
def func0(self, objclass=BaseClassA):
self.class_a_obj = objclass()
obj1 = BlassClassB()
obj1.func0()
obj2 = BassClassB()
obj2.func0(objclass = ExtendClassA)
So, I've tried a PoC that, if I understand correctly, might do the trick. Give it a look.
By the way, whether it does work or not, I have a strong feeling this is actually a bad practice in almost all scenarios, as it changes class behavior in a obscure, unexpected way that would be very difficult to debug.
For example, in the below PoC if you inherit the same BaseClassA multiple times - only the latter inheritance shall be written in the class library, which would be a huge pain for the programmer trying to understand what on earth is happening with his code and why.
But of course, there are some use cases when shooting ourselves in a leg is less painful than designing & using a proper architecture :)
So, the first example where we have inheritance (I specified multiple inherited classes, just to show that only the last inherited one would be saved in a library):
#################################
# 1. We define all base classes
class BaseClassA:
def whoami(self):
print(type(self))
def __init_subclass__(cls):
omfg_that_feels_like_a_reeeeally_bad_practise['ClassA'] = cls
print('Class Dict Updated:')
print('New Class A: ' + str(cls))
#################################
# 2. We define a class library
global omfg_that_feels_like_a_reeeeally_bad_practise
omfg_that_feels_like_a_reeeeally_bad_practise = {}
omfg_that_feels_like_a_reeeeally_bad_practise['ClassA'] = BaseClassA
#################################
# 3. We define a first class that refer our base class (before inheriting from base class)
class UserClassA:
def __init__(self):
self.class_a_obj = omfg_that_feels_like_a_reeeeally_bad_practise['ClassA']()
#################################
# 4. We inherit from the base class several times
class FirstExtendedClassA(BaseClassA):
pass
class SecondExtendedClassA(BaseClassA):
pass
class SuperExtendedClassA(FirstExtendedClassA):
pass
#################################
# 5. We define a second class that refer our base class (after inheriting from base class)
class UserClassB:
def __init__(self):
self.class_a_obj = omfg_that_feels_like_a_reeeeally_bad_practise['ClassA']()
#################################
## 6. Now we try to refer both user classes
insane_class_test = UserClassA()
print(str(insane_class_test.class_a_obj))
### LOOK - A LAST INHERITED CHILD CLASS OBJECT IS USED!
# <__main__.SuperExtendedClassA object at 0x00000DEADBEEF>
insane_class_test = UserClassB()
print(str(insane_class_test.class_a_obj))
### LOOK - A LAST INHERITED CHILD CLASS OBJECT IS USED!
# <__main__.SuperExtendedClassA object at 0x00000DEADBEEF>
And if we remove inheritance, the base class will be used:
#################################
# 1. We define all base classes
class BaseClassA:
def whoami(self):
print(type(self))
def __init_subclass__(cls):
omfg_that_feels_like_a_reeeeally_bad_practise['ClassA'] = cls
print('Class Dict Updated:')
print('New Class A: ' + str(cls))
#################################
# 2. We define a class library
global omfg_that_feels_like_a_reeeeally_bad_practise
omfg_that_feels_like_a_reeeeally_bad_practise = {}
omfg_that_feels_like_a_reeeeally_bad_practise['ClassA'] = BaseClassA
#################################
# 3. We define a first class that refer our base class
class UserClassA:
def __init__(self):
self.class_a_obj = omfg_that_feels_like_a_reeeeally_bad_practise['ClassA']()
#################################
# 5. We define a second class that refer our base class
class UserClassB:
def __init__(self):
self.class_a_obj = omfg_that_feels_like_a_reeeeally_bad_practise['ClassA']()
#################################
## 6. Now we try to refer both user classes
insane_class_test = UserClassA()
print(str(insane_class_test.class_a_obj))
### LOOK - A DEFAULT CLASS OBJECT IS USED!
# <__main__.BaseClassA object at 0x00000DEADBEEF>
insane_class_test = UserClassB()
print(str(insane_class_test.class_a_obj))
### LOOK - A DEFAULT CLASS OBJECT IS USED!
# <__main__.BaseClassA object at 0x00000DEADBEEF>

How to Access variable and functions of any class in a different class in python

import copy
class Myclass0:
paperlist=[]
class Myclass1:
def copy_something(self):
Paper = Myclass0()
Flowers = ["Roses","Sunflower","Tulips","Marigold"]
Paper.paperlist = copy.copy(Flowers)
class Myclass3:
superlist = []
Paper = Myclass0()
print(Paper.paperlist)
superlist.append(paperlist[0])
I am getting a index out of range error on compiling.please help me finding a way to print paperlist of Myclass0 in Myclass3 using class Myclass1 Functions and attributes.You can change the class body but All the Classes should be used.
I am waiting for your valuable efforts.
Thank You
maybe this code snippet could help you understand it better:
class MyClass0:
def __init__(self):
# this is now an attribute of the instance (not the class)
self.paperlist = []
class MyClass1:
#staticmethod
def copy_something(paper):
# this is a static method (it doesnt rely on the Class (MyClass1) or an instance of it
flowers = ["Roses", "Sunflower", "Tulips", "Marigold"]
paper.paperlist = flowers
class Myclass3:
def __init__(self, paper):
# when an instance of this class is created an instance of MyClass0
# must pre passed to its constructor. It then prints out its paperlist
print(paper.paperlist)
paper = MyClass0()
MyClass1.copy_something(paper)
Myclass3(paper)

Initialize variable if class method is run

I have a class, like
class D:
def __init__(self):
"""some variables"""
def foo(self):
"""generates lots of data"""
I would like to be able to store all of the data that foo creates within the instance of the class that foo is being called from. Almost like creating a new initialization variable, but only once the method is called. For if the user never calls foo, no need to have generated the data to begin with.
Thanks!
How about to make a flag which will say if data was already generated?
class D:
def __init__(self):
self.already_generated = False
"""some variables"""
def foo(self):
"""generates lots of data"""
if not already_generated:
self.generate()...
already_generated = True
def generate(self,...):
Not quite sure if this is what you're trying to do, but if you want a class method to generate data that can be accessed from that instance you can put it into a data structure that is a member of that class:
class D:
def __init__(self):
#class member variables here
self.fooArray = []
def foo(self):
#insert your data to self.fooArray here, eg:
for i in range(1, 10000):
self.fooArray.append(i)

Python: How to Encapsulate a Variable Across Multiple Classes?

I have a script using threaded timers that manipulates 2 common lists at random.
Because the class instances manipulate the lists on threaded timers, I cannot pass the variables to the classes & back.
…All instances of the classes need to manipulate a single, up to date list.
Because of that, the scope of those lists are set to global. However, I need the scope to be at the class level, yet be manipulated by multiple classes.
To clarify...
Here's the basic program structure:
Global list variable_1
Global list variable_2
class MasterClass:
# this creates instances of the threaded classes.
There are 50+ instances of MasterClass creating thousands
of instances of ThreadedClass1, 2, & 3. All manipulate
global list variables 1 & 2.
class ThreadedClass1:
# threaded classes manipulate global list variables 1 & 2 on random timers.
class ThreadedClass2:
class ThreadedClass3:
The problem: For each instance of MasterClass I need a separate list variable 1 & 2. Each instance of ThreadedClasses called by that instance of MasterClass must manipulate only the list variables owned by that instance of MasterClass.
Basically I need the equivalent of a global list variable, but I need it to be encapsulated by an instance of MasterClass, and be manipulated by any instance of ThreadedClasses called by that instance of MasterClass only.
How's this done?
Try to pass instance of MasterClass to every produced instance of ThreadedClasses.
Then, define thread save methods in MasterClass, that will perform manipulation with your variable_1, variable_2. ThreadedClasses shall not touch this lists directly, only by calling those methods.
Small example (check subclassing from object):
import threading
class ThreadedClassBase(object):
def __init__(self, master, *args, **kwargs):
self.master = master
def do_something(self):
self.master.append(1, 'some_value')
value = self.master.getitem(1, 0)
class ThreadedClass1(ThreadedClassBase):
def __init__(self, *args, **kwargs):
super(ThreadedClass1, self).__init__(*args, **kwargs)
# ...
# same for ThreadedClass2, 3
class MasterClass(object):
def __init__(self, *args, **kwargs):
self.variable_1 = list()
self.variable_2 = list()
self.lock = threading.Lock()
for i in range(50):
ThreadedClass1(master=self)
# create new thread
def append(list_nb, value):
with self.lock:
getattr('variable_' + list_nb).append(value)
def getitem(list_nb, index):
with self.lock:
return getattr('variable_' + list_nb)[index]
If I understand correctly, you should be able to make them instance variables of MasterClass and pass them into the constructors.
eg.
class MasterClass:
def __init__(self):
self.variable_1 = [...]
self.variable_2 = [...]
self.tc1 = ThreadedClass1(self.variable_1, self.variable_2)
self.tc2 = ThreadedClass2(self.variable_1, self.variable_2)
self.tc3 = ThreadedClass3(self.variable_1, self.variable_2)
Alternatively pass the whole instance in
class MasterClass:
def __init__(self):
self.variable_1 = [...]
self.variable_2 = [...]
self.tc1 = ThreadedClass1(self)
self.tc2 = ThreadedClass2(self)
self.tc3 = ThreadedClass3(self)
class ThreadedClass1:
def __init__(self, parent):
self.mc = parent
etc.

Python - Inheritance

I'm not understanding any online documentation about how to make inheritance work.
I have this here:
import maya.cmds as cmds
class RigLegs():
def __init__(self, *args):
self.rigLegs()
def rigLegs(self):
self.items["side"] = "left"
self.lIK = cmds.duplicate(self.lJoints["hip"], n = self.getName("hip_IK"))
for i in self.lIK:
newName = i[0].replace("_JNT", "_IK")
cmds.rename(i, newName)
But it's complaining that there is no self.items - I have to inherit it from another class which is far too large to post here. Can anyone help me figure out how to do that? I've researched online and nothing makes any sense.
The other class is in a different file altogether.
To inherit from another class do:
class RigLegs(base_class_name):
An Example:
class base_class():
items = [1,2,3]
class pie(base_class):
def __init__(self):
print (self.items)
instance = pie()
You can read more in the Python Documentation
With imports:
file (apples.py)
class base():
items = [1,3,4]
file (main_file.py)
import apples
class pie(apples.base):
def __init__(self):
self.pies()
def pies(self):
print(self.items)
instance = pie()
In the class declaration: class RigLegs(), you should include all the classes you want to inherit from, such as in:
class RigLegs(Ancestor1, Ancestor2):
# Your code chere.
Don't forget that you still need to call the initialization logic of your ancestors.
def __init__(self):
super(RigLegs, self).__init__()

Categories