Python change object reference from object itself - python

Consider the following code:
class A:
def hi(self):
print 'A'
def change(self):
self = B()
class B(A):
def hi(self):
print 'B'
and
test = A()
test.hi() -> prints A
test.change()
test.hi() -> prints A, should print B
Is there some way to make this principle work, so changing the object reference 'test' from withing the class/object itself?

Objects have no concept of the variable that contains them - thus, you can't do exactly what you're trying to do.
What you could do is have a container that is aware of the thing it contains:
class Container(object):
def __init__(self):
self.thing = A()
def change(self):
self.thing = B()
def hi(self):
self.thing.hi()
test = Container()
test.hi() # prints A
test.change()
test.hi() # prints B

Related

Python : Convert Superclass instance to Subclass

I am given an object a of the class A. I do not understand how class A works. Furthermore an unknown number of methods throughout the module I am using use A. So for all practical purposes A is unknown and we can only manipulate an instance of it and one known method, method2.
I am given an instance a. I want to convert a to a class B such that it remains identical in every respect except that method2 (which was present in the original class A and prints a) now prints b. How do I modify the piece of code below to be able to do that ?
class B(A):
def __init__(self,**kwargs):
super().__init__(**kwargs)
def method2(self):
print('b')
a.method1() #prints '1'
a.method2() #prints 'a'
print(a[0]) #prints 1
#a = convertAtoB(a)
a.method1() #prints '1'
a.method2() #should print 'b'
print(a[0]) #prints 1
I am aware of a previous answer to a similar question which involved using __getattr__ however when trying the below piece of code:
class B(object):
def __init__(self, a):
self.__a = a
def __getattr__(self, attr):
return getattr(self.__a, attr)
def __setattr__(self, attr, val):
object.__setattr__(self, attr, val)
def method2(self):
print('b')
I got, in the practical problem I am having, the error TypeError: 'B' object is not subscriptable.
edit : added a subscript test, as I mentioned above, I don't entirely understand how A works or which methods in the imported module need A to work.
You can reassign object's __class__ to a new type. I've put comment inside the code: (take care of object initialization yourself if necessary)
class A:
def func_A_1(self):
return 'func_A_1 is running'
def func_A_2(self):
return 'func_A_2 is running'
def method2(self):
return 'method2 of class A'
class B(A):
def method2(self):
return 'method2 of class B'
obj = A()
print(obj)
print(obj.func_A_1())
print(obj.method2())
print('------------------------------')
# turning object of A to B
obj.__class__ = B
print(obj)
# still have access to A's methods
print(obj.func_A_1())
# This method is now for B
print(obj.method2())
output :
<__main__.A object at 0x0000012FECFACFD0>
func_A_1 is running
method2 of class A
------------------------------
<__main__.B object at 0x0000012FECFACFD0>
func_A_1 is running
method2 of class B
Don't override __init__, only override method2, and just set a = B(). Or:
class B(A):
def method2(self):
print('b')
def convertAtoB(a):
a.method2 = B().method2
return a
a.method1() #prints '1'
a.method2() #prints 'a'
#a = convertAtoB(a)
a.method1() #prints '1'
a.method2() #should print 'b'

How to access objects from a different class?

There are three classes :
A, B and C
The __init__ of B creates an object of A. Using the mutators, I will be able to change the attributes of A from B for the instance created.
However, I am not unable to find any way to use that instance of A created by B to be used in C without passing the Object explicitly to the __init__ method [ not C.__init(self, object: A) ]
Is there any way to implicitly allow C to use that instance of A ?
I am new to python and not sure if this a valid question. I have looked at other sources where it explicitly passes the object to class C
class A:
def __init__(self):
x = []
y = []
class C :
def __init__(self):
#[get obj1 without passing the instance in init]
self.value = None
def method1():
self.value = len([]) #len(obj1 of A.x)
class B:
def __init__(self):
obj1 = A()
obj1.x = [1,2,3,4]
obj1.y = [1,2,3]
obj2 = B()
print(obj2.value) #this should be the length of x in the instance A created above
Here is a simple example:
class A:
def __init__(self, i = ""):
self.item = i
class B:
def __init__(self):
self.a = A("hello")
class C:
def __init__(self):
b = B()
print(b.a.item)
c = C()
Output:
hello
Let's say we have classes A and B:
class A:
def hello_world(self):
print("hello world")
class B:
def __init__(self):
self.a = A()
def hello_world(self):
self.a.hello_world()
You create an instance of class B (which will create an instance of class A inside):
b = B()
You can then pass a reference to either b or b.a to any function of an instance of class C (either a constructor or not)
class C:
def hello_world(self, a):
a.hello_world()
c = C()
c.hello_world(b.a)
You can also use global variables:
class C:
def hello_world(self):
b.a.hello_world()
c = C()
c.hello_world()
Here the instances of class C will rely on variable b to be in place and just use its a attribute.
Using global variables in classes is generally considered to be hard to maintain and a bad practice. If your class depends on a value or an instance of some class you should pass the reference in the constructor (__init__ function) or in the function that's using it.
If these classes are in different different python files then you can also use these classes by importing the class name and creating an object of that class:
eg:
file1.py
class A:
def __init__(self):
x = []
y = []
file2.py
from file1 import A
class C :
def __init__(self):
[get obj1 without passing the instance in init]
self.value = None
self.obj_a = A()
def xyz(self):
print "in class c"
file3.py
from file2 import C
from file1 import A
Class B:
def __init__(self):
self.obj_a = A()
self.obj_c = C()
def another_func(self):
print self.obj_c.xyz()# it will print "in class c"

How to access a class variable from another class in python?

I have the following code segment :
class A:
def __init__(self):
self.state = 'CHAT'
def method1(self):
self.state = 'SEND'
def printer(self):
print self.state
class B(A):
def method2(self):
self.method1()
print self.state
ob_B = B()
ob_A = A()
ob_B.method2()
ob_A.printer()
This gives me the output :
SEND
CHAT
I want it to print :
SEND
SEND
That is, when B.method2 is modifying self.state by calling self.method1, I want it to modify the already existing value of self.state = 'CHAT' in A's instance. How can I do this?
The instance is passed as the first argument to each of your methods, so self is the instance. You are setting instance attributes and not class variables.
class A:
def __init__(self):
A.state = 'CHAT'
def method1(self):
A.state = 'SEND'
def printer(self):
print A.state
class B(A):
def method2(self):
self.method1()
print B.state
ob_B = B()
ob_A = A()
ob_B.method2()
ob_A.printer()
SEND
SEND
ob_B = B()
ob_A = A()
ob_B.method2()
ob_A.printer()
You need to call ob_B.method2() -- without the parentheses that statement is just a reference to the function and doesn't actually call it.
You can call the printer() method by using object of B so that you will get the updated value.
ob_B = B()
ob_A = A()
ob_B.method2()
ob_B.printer()

How to copy a member function of another class into myclass in python?

I have a utility class from which I want to use one of the member function in another class. I don't want to inherit from that class. I just want to re-use the code from one of the member function of the other class. Kind of partial inheritance.
class HugeClass():
def interestedFunc(self,arg1):
doSomething(self.someMember1)
def OtherFunctions(self):
...
class MyClass():
def __init__(self):
self.someMember1 = "myValue"
self.interestedFunc = MagicFunc(HugeClass.interestedFunc)
c = MyClass()
print c.interestedFunc(arg)
Is there such a MagicFunc in python?
You can do what you want ie.:
class Foo(object):
def foo(self):
print self.a
class Bar(object):
foo = Foo.__dict__['foo']
b = Bar()
b.a = 1
b.foo()
But are you sure that this is good idea?
It seems like the __dict__ part from the older answer is not required in Python 3
This works fine:
class Foo:
def foo(self):
print self.a
class Bar:
foo = Foo.foo
b = Bar()
b.a = 1
b.foo()

python/pygame, pass input from a class to another class

there is a way to pass a value or a variable from a class to another class without having to pass through the main function
I'm using python
well, of course you can access other objects attributes in methods of a specific object. e.g:
class A(object):
def method(self, other):
other.somevar = 5
class B(object):
pass
def main():
a = A()
b = B()
b.somevar = "Hello World"
a.method(b)
print(b.somevar) # now prints '5'

Categories