Python class multiple initialization definition based on where it is initialized - python

What i want to do is make an object do different initializations based on where it is instanciated.
For example
class Test:
def __init__(self):
self.a = 1
def __init2__(self):
self.a = 2
So that the normal init is run when the class Test is called on it's own
t = Test()
print(t.a)
>>> 1
And when it is on a list it runs inside a List it runs the second init
t = [Test()]
print(t[0].a)
>>> 2
Is this possible in python?

You can try a different approach, and just use a #classmethod as a factory method that creates an instance for the specific case:
class Test:
def __init__(self, a=1):
self.a = a
#classmethod
def in_list(cls):
return cls(2)
so, in the list you can call:
t = [Test.in_list()]
print(t[0].a)
>>> 2

Related

Why #property broke synchronizing with source object on proxy class

I want to create a proxy in Python because of function and attributes access (something like private). I create the proxy with references to functions in the source object. But I have a problem, that functions have no problem with changing attributes but property yes. Here is an example:
A working example
class A:
def __init__(self):
self.value = 1
def get_value(self):
return self.value
class Proxy:
def __init__(self, cls):
self.get_value = cls.get_value
# del cls
a = A()
p = Proxy(a)
print(a.get_value(), p.get_value())
a.value = 2
print(a.get_value(), p.get_value())
Output:
1 1
2 2
Not working:
class A:
def __init__(self):
self.value = 1
#property
def get_value(self):
return self.value
class Proxy:
def __init__(self, cls):
self.get_value = cls.get_value
# del cls
a = A()
p = Proxy(a)
print(a.get_value, p.get_value)
a.value = 2
print(a.get_value, p.get_value)
Output:
1 1
2 1
Can someone explain me where the problem is and if there is any solution for this? I could use functions, but I think #property is more Python solution. And I really want to know what is the difference. Thank you
In Proxy.__init__, you end up executing:
self.get_value = a.get_value
and very different things happen in your two examples.
In the first case, a.get_value is a method of a. So, calling p.get_value() is the same as calling a.get_value(). You get identical results.
In the second case, you have already defined a.get_value as a property, so self.get_value = a.get_value is basically self.get_value = 2, it is just an int attribute of p.

get object on which a method was called in Python

Is there a way in Python to get a reference to an object on which a method was called?
And in case it is, is it possible even in a nested way?
my_class.py:
from modules import math_ops
class A():
def __init__(self):
self.math_ops = math_ops.B()
self.number = 1
modules/math_ops.py:
class B():
def add_1():
where_to_add = # Get instance of A() object
where_to_add.number += 1
To execute this:
>>> a = A()
>>> a.math_ops.add_1()
And get this:
>>> a.number
2
I'm asking because I am interested in writing a static method which works with the object on which it was called, but would like to avoid using the object as an argument as it would be much nicer to call a method like my_object.prop.static_method() instead of my_object.prop.static_method(my_object).
If you never plan on reassigning math_ops outside A, this is fairly simple to do.
from modules import math_ops
class A():
def __init__():
self.math_ops = math_ops.B(self)
self.number = 1
modules/math_ops.py:
class B():
def __init__(self, creator):
self.creator = creator
def add_1():
creator.number += 1
I will mention it again in case you skimmed the first line, the following will generate unexpected results since B is tracking the creator of the object rather than the caller.
a1 = A()
a2 = A()
a1.math_ops = a2.math_ops
a1.math_ops.add_1() # a2 is updated
If that looks like something you might wanna do, the answer is a tad more complicated. Here's my attempt:
from modules import math_ops
class A():
def __init__(self):
self._math_ops = math_ops.B(self)
self.number = 1
#property
def math_ops(self):
self._math_ops.set_caller(self)
return self._math_ops
#math_ops.setter
def math_ops(self, new_math_ops):
self._math_ops = new_math_ops
modules/math_ops.py:
class B():
def __init__(self, caller):
self.caller = caller
def set_caller(self, caller):
self.caller = caller
def add_1(self):
self.caller.number += 1
class A():
number = 1
class B():
def add_1():
where_to_add = A
where_to_add.number += 1
B.add_1()
print(A.number)
B.add_1()
print(A.number)
B.add_1()
print(A.number)

Using a method both inside a class and outside - python

So I have a function that, so far, I have had as a method inside a class. Turns out now I want to use it without making an instance of the class.
What is the best way of doing this without having to massively change the code?
Example codes follow:
Before:
class A(object):
def method1(self, input):
return input*3 + 7
def method2(self, input):
return self.method1(input) + 4
Basically I want to take method1 out of the class so that i can use it without making an instance of A, but also do not want change self.method1 to method1 everywhere.
My idea:
def method1(input):
return input*3 + 7
class A(object):
def __init__(self):
self.method1 = method1
def method2(self, input):
return self.method1(input) + 4
--
Is this bad practice? How else could one call a method from inside a class? Or alternatively how can a class incorporate methods methods outside it?
Try this:
def method1(input):
return input*3 + 7
class A(object):
def method1(self, input):
return method1(input)
def method2(self, input):
return self.method1(input) + 4
this should work
It won't work because of the self parameter. Instead, define it like this:
class A(object):
def method1(self, input):
return method1(input)
This is called a static method in order to do this, your function can not contain (self)
class A(object):
def method_one(variable):
return variable * 3 + 7
def method_two(self, variable):
return self.method_one(variable) + 4
print(A.method_one(10))
(xenial)vash#localhost:~/python/stack_overflow$ python3.7 method_out.py
37
Turn into a staticmethod the method you don't need or don't want an instance of its class.
The ideia would be like the following:
>>> class A:
#staticmethod
def m(value):
return value*3+7
def sum(self, value):
return self.m(value) + 4
>>> a = A()
>>> a.sum(4)
23
>>> 4+A.m(4)
23
>>>
Notice the difference from a normal method to the static one. On the static one you ommit the self parameter, thus meaning you don't need an instance of its class to use that static method.

How do I pass a whole class as a parameter to another class`s method

Is it possible to pass a whole class (not an instance) as a parameter to another class method in Python? If I have several instances of the class first and need to pass any of them not specifying which one to method of class Second, can I do something like this:
class First():
def __init__(self, a, b):
pass
class Second():
def __init__(self, c, d):
pass
def method(self, First):
#and how do I call here the whole class First
#without calling a particular instance here?
Straightforward.
def method(self, First):
First() #instantiation
First.classmethod()
First.staticmethod()
In python classes are objects itself, so you are able to call your method like this
second_instance.method(Any_Class_You_Want)
First, you don't need to specify types in Python. So, if you want method to take a First instance, just do this:
class Second():
def __init__(self, c, d):
pass
def method(self, first):
pass
my_first = First(0, 1)
my_second = Second(2, 3)
my_second.method(my_first)
I believe that answers your real question, which is:
If I have several instances of the class first and need to pass any of them not specifying which one to method of class Second…
If you want to ensure that the parameter actually is a First, you can always add an assert isinstance(first, First) or if not isinstance(first, First): raise TypeError or whatever, but usually you don't want to do that in Python. The whole point of "duck typing" is that you write a function that takes "anything that acts like a First instance" rather than a function that takes "a First instance".
You then say:
Now I need to mutate variables from the First class inside the method of a second class:
So… just do it. Your example doesn't have any attributes in the First class, so let's add some:
class First():
def __init__(self, a, b):
self.total = a + b
And now, let's use them in Second.method:
class Second():
def __init__(self, c, d):
self.total = c + d
def method(self, first):
first.total += self.total
So:
>>> my_first = First(0, 1)
>>> my_first.total
1
>>> my_second = Second(2, 3)
>>> my_second.total
5
>>> my_first.total += 2
>>> my_first.total
3
>>> my_second.method(my_first)
>>> my_first.total
8
Or, if you meant that you wanted to mutate the class attributes in class First… you don't even need a First instance for that:
First.my_class_attribute = 1
If you really do need to pass a class itself… well, a class is a regular value like anything else:
class Second():
def __init__(self, c, d):
pass
def method(self, cls):
pass
my_second = Second(1, 2)
my_second.method(First)
And you can access the class attributes of cls from within method, just as easily as you can access instance attributes when an instance is passed.
You can do:
class Model1:
def get():
return '1'
class Model2:
def get(Model1):
print('test: '+ str(Model1.get()))
if __name__ == '__main__':
Model2.get(Model1)
the output is;: test: 1

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