Access attribute of one instance from another instance defined in that instance - python

Sorry for the confusing question.
Say there are two instances of two different classes (e.g. 'big_instance' and 'little_instance').
The little_instance is defined as an attribute of the big instance.
How would a method in the little class access an attribute of the big instance.
An example is below.
The line 'return parent.attribute1' is basically pseudo code. How would this line be written properly?
class BigClass:
def __init__(self, att):
self.attribute1 = att
self.little_instance = LittleClass()
class LittleClass:
def parents_att(self):
return parent.attribute1
big_instance = BigClass(1)
print(big_instance.little_instance.parents_att())

ah yes I got it. Read the comments for explanation.
The test code at the end shows that it works even after attribute1 changes :)
class BigClass:
def __init__(self, att):
self.attribute1 = att
# pass in self
self.little_instance = LittleClass(self)
class LittleClass:
def __init__(self, the_big_class):
# the big class is held in an instance var
self.the_big_class = the_big_class
def parents_att(self):
# the instance var is used to reference the attribute
return self.the_big_class.attribute1
big_instance = BigClass(1)
print(big_instance.little_instance.parents_att())
big_instance.attribute1 = 2
print(big_instance.little_instance.parents_att())

You can do the following if you want to access attribute from BigClass into LittleClass.
class BigClass:
def __init__(self, att):
self.attribute1 = att
class LittleClass(BigClass):
def __init__(self, att):
BigClass.__init__(self, att)
def parent_att(self):
return self.attribute1
small_instance = LittleClass(1)
print(small_instance.parent_att)

Related

Anyone knows how to create an attribute of a Class which will be a '''set''' of all instances of that class?

I know that each instance will inherit that attribute, but I want a function or should I call it a method of that class to return the set of all instances created of that class.
So let's say I created 3 instances and call a method from the last one that will return all the previously created instances as well as the one that I am calling it from.
I was able to achieve it by making a list, but would it be possible to return a set?
Is there some kind of constructor that I am missing for it?
class Bee():
instances = []
def __init__(self, name, identifier):
self.name = name
self.identifier = identifier
def __str__(self):
self.instances.append(f"{self.identifier} {self.name}")
return f"{self.identifier} {self.name}"
def get_hive(self):
return self.instances
Normally you would create Hive as a separate class and put the Bees inside. You then have a clear and explicit data structure whose job includes keeping track of all Bees created.
Something like:
class Hive:
def __init__(self):
self.bees = []
def add_bee(self, bee):
self.bees.append(bee)
class Bee:
def __init__(self, name, identifier):
self.name = name
self.identifier = identifier
def __str__(self):
return f"Bee({self.name}, {self.identifier})"
def __repr__(self):
return str(self)
# User code example
hive = Hive()
b1 = Bee('My Bee', 0)
b2 = Bee('Some Other Bee', 1)
hive.add_bee(b1)
hive.add_bee(b2)
print(hive.bees) # display all bees inside the hive

Create child class object using parent class instance

lets say we have class A and it has one instance - x. How to make a child class of class A where I would be able to pass x as an argument and get all its parameters and pass it to child class object. precisely speaking I want to do something like this.
class A:
def __init__(self, parameter1, parameter2):
self.parameter1 = parameter1
self.parameter2 = parameter2
class B(A):
def __init__(self, Ainstance, someParameter):
super().__init__(**Ainstance.__dict__)
self.someParameter = someParameter
x = A(parameter1='1', parameter2='2')
x = B(x, someParameter='3')
print(x.parameter1)
print(x.parameter2)
print(x.someParameter)
the goal is to create a class where I would be able to get all the parameters of parent class object, and add my own attributes. The problem in the code above is I won't be able to do that with all classes because not all of them has __dict__ attribute.
I have this example code which I use to remind myself how to construct a proxy.
#soProxyPattern
class Example:
def __init__(self):
self.tag_name = 'name'
def foo(self):
return 'foo'
def bar(self, param):
return param
class Container:
def __init__(self, contained):
self.contained = contained
self.user_name = 'username'
def zoo(self):
return 0
def __getattr__(self, item):
if hasattr(self.contained, item):
return getattr(self.contained,item)
#raise item
c = Container(Example())
print(c.zoo())
print(c.foo())
print(c.bar('BAR'))
print(c.tag_name)
print(c.user_name)
The output is:
0
foo
BAR
name
username
This shows that Container can have its own attributes (methods or variables) which you can access over and above all of the attributes of the contained instance.
Instead of dict you could use the dir and getattr like this:
class A:
def __init__(self, parameter1, parameter2):
self.parameter1 = parameter1
self.parameter2 = parameter2
class B(A):
def __init__(self, Ainstance, someParameter):
parameters = {param: getattr(Ainstance, param) for param in dir(Ainstance) if not param.startswith("__")}
super().__init__(**parameters)
self.someParameter = someParameter
For a more detailed explanation see: Get all object attributes in Python?

Turning a class member into an object member after class declaration

Usually one initializes class members inside the class (not into the constructor) and the references them via MyClass.mymember instead of self.mymember.
However I noticed that I can actually reference the member later via self.mymember. Further, I can even overwrite it. This has the very curious effect, that the class member becomes an instance member.
This effect can be seen in the following code with property_cache of MyClass.
It is really helpful in this context, because now the object property_cache (not the class PropertyCache!) can be used as a decorator and it is a instance member of myclass(not a class member of MyClass!).
However, the effect that a class member is turned into an instance member after the declaration of MyClass is very unexpected. I did not even consider that such a thing is possible and I don't quite understand this mechanism.
Can someone shed some light on it and possible reference some literature on this? I did not find a description in the documentation of python.
class PropertyCache:
def __init__(self):
self.cache = {}
def reset(self):
self.cache = {}
def __call__(this, function):
def wrapper(self, *args, **kwargs):
if function.__qualname__ not in self.property_cache.cache:
self.property_cache.cache[function.__qualname__] = function(self, *args, **kwargs)
return self.property_cache.cache[function.__qualname__]
return wrapper
class MyClass:
property_cache = PropertyCache()
def __init__(self, parameter):
self.parameter = parameter
self.property_cache = PropertyCache()
def fit(self, data):
print('fit')
self.intermediate_data_ = data + self.parameter + 2
self.property_cache.reset()
return self
#property
#property_cache
def trans1(self):
print('trans 1')
return self.intermediate_data_ / self.parameter / 2
#property
#property_cache
def trans2(self):
print('trans 2')
return self.intermediate_data_ / self.parameter / 5
myclass = MyClass(2)
myclass.fit(10)
myclass.trans1
myclass.trans1
myclass.trans2
myclass.fit(15)
myclass.trans1
myclass.trans1
myclass.trans2
myclass2 = MyClass(3)
myclass2.fit(15)
myclass2.trans2
myclass2.trans2
myclass.trans2

Define methods for multiple classes

I'm working on a small personal project where I created many classes. Each class has its own register containing all its instances:
class IterReg(type):
# Register of all objects for iteration
def __iter__(cls):
return iter(cls._reg.values())
The "template" which I use for each class is
class Point(object):
# Point object
__metaclass__ = IterReg
_reg = dict()
counter = 0
# Initialize
def __init__(self, name):
self.name = name
self._reg[self.name] = self
Point.counter += 1
# Return register keys
#staticmethod
def get_reg_keys(cls):
return cls._reg.keys()
And some other (not important for a MWE) stuff.
If I initialize, e.g., a = Point("Point A"), I can then call:
>>> a.get_reg_keys()
['Point A']
which is (obviously) the same result that I get from
Point.get_reg_keys()
Now my question: is there a way to define this method once for all classes (i.e. somehow in the metaclass).
I first thought something like this had worked:
class IterReg(type):
# Register of all objects for iteration
def __iter__(cls):
return iter(cls._reg.values())
def get_reg_keys(cls):
return cls._reg.keys()
But then I can just call get_reg_keys() from the class (i.e. Point.get_reg_keys()) and not from any instance of it.
You can define a generic class that has .get_reg_keys() and subclass it when you want to use that method. In the below example, any class that inherits from Generic will have the .get_reg_keys() method.
class IterReg(type):
# Register of all objects for iteration
def __iter__(cls):
return iter(cls._reg.values())
class Generic(object):
#classmethod
def get_reg_keys(cls):
return cls._reg.keys()
class Point(Generic):
# Point object
__metaclass__ = IterReg
_reg = dict()
counter = 0
# Initialize
def __init__(self, name):
self.name = name
self._reg[self.name] = self
Point.counter += 1
a = Point('Point A')
a.get_reg_keys()
# returns:
['Point A']

How to get the object instance by its variable

Suppose I will send self.f to a global method,
def write_to_report(file_hdlr, content):
If I want get the what the object is the file_hdlr belonged to.
How to get it ? Because I need to know the file_hanlder is belonging which Class,
and use the class name to do somthing
def write_to_report(file_hdlr, content):
file_hdlr.__self__ # ??? NO
CODE
class MemoryInfo(threading.Thread):
def __init__(self, config):
self.f = get_export_file_hdlr(self.__class__.__name__)
class CPUInfo(threading.Thread):
def __init__(self, config):
self.f = get_export_file_hdlr(self.__class__.__name__)
You can't.
A different approach:
class ReportWriterMixin(object):
def write_to_report(self):
this_class = self.__class__
# do thing with self.f based on this_class
class CPUInfo(threading.Thread, ReportWriterMixin):
def __init__(self, config):
self.f = get_export_file_hdlr(self.__class__.__name__)
self.write_to_report()
This way, while your method is no longer "global", it can be made available to any class you like
If you want to know the type of file_hdlr variable, you can use function type:
file_hdlr_type = type(file_hdlr)

Categories

Resources