Python: getting class type within class - python

I have a python class and I want to type-check within the class for itself. For example: Using python class 'A':
class A:
def __init__(self, param1, ...):
self._param1 = None
self.param1= param1
#property
def param1(self):
return self._param1
#param1.setter
#type_check_property(******)
def param1(self, param1):
self._param1 = param1
I define my first class and want to pass that into a second class and have it type-checked to make sure it is of type(A).
class1 = A(....)
class2 = A(param1=class1, ...)
I have a decorator that can already do this, but I need to pass (A instead of ****** in the first block of code) but I can't get A because A hasn't been instantiated yet.
How do I go about getting the type of a class within the class itself?
Thanks!

You have to do this after the class definition, inside the class definition, the class object doesn't exist yet. So:
class A:
def __init__(self, param1):
self.param1= param1
#property
def param1(self):
return self._param1
def _param1_setter(self, param1):
self._param1 = param1
A.param1 = A.param1.setter(type_check_property(A)(A._param1_setter))
A key thing to understand here,
#foo
#bar
def baz():
pass
Is equivalent to:
def baz():
pass
baz = foo(bar(baz))
And:
#bar(arg)
def baz():
pass
is equivalent to:
def baz():
pass
baz = bar(arg)(baz)
So putting it all together:
#foo
#bar(arg)
def baz():
pass
is equivalent to:
def baz():
pass
baz = foo(bar(arg)(baz))

Related

How do I pass a default method as a parameter in Python

Here is my code:
class class1():
def __init__(self):
pass
def method1(self):
pass
def independent_method(class1_instance, param2='method1'):
return class1_instance.param2()
c = class1()
independent_method(c)
I get this error:
'class1' object has no attribute 'param2'
How do I get around this problem? I've tried different variations.
Use __getattribute__ to fetch the method by its given name in param2:
class class1():
def __init__(self):
pass
def method1(self):
pass
def independent_method(class1_instance, param2='method1'):
return class1_instance.__getattribute__(param2)()
c = class1()
independent_method(c)
You can also use getattr... that's actually a better way to do so.
class class1():
def __init__(self):
pass
def method1(self):
pass
def independent_method(class1_instance, param2='method1'):
return getattr(class1_instance, param2)()
c = class1()
independent_method(c)

Can we pass the class object inside its own method?

I have a class A object method which uses another class B object's method, which the argument is class A object.
class A():
def calculate(self):
B = B.calculator(A)
class B():
def calculator(self, A):
...do something with A.attributes
It is possible to just pass attributes into the object, but I would see this possibility as the last priority. I am definitely a bit oversimplify my case, but I am wondering if there is a way to pass the entire class
Edit:
Sorry for the confusion. At the end I am trying to call class A object and A.calculate(), which will call class B obj and calculator function.
class A():
def __init__(self, value):
self.value = value
def calculate(self):
Bobj = B()
Bobj.calculator(A)
class B():
def calculator(self, A):
...do something with A.value
def main():
Aobj = A(value)
Aobj.calculate()
Your scenario does not currently indicate that you want to use any information from B when calculating A. There are a few ways of getting the functionality that you want.
Scenario: B stores no information and performs calculation. B should be a function
def B(value):
```do something with value```
return
class A():
def __init__(self, value):
self.value = value
def calculate(self):
return B(self.value)
def main():
Aobj = A(value)
Aobj.calculate()
Scenario: B stores some other information, but internal B information is not needed for the calculation. B should have a static method
class B():
#staticmethod
def calculate(value):
```do something with value```
return
class A():
def __init__(self, value):
self.value = value
def calculate(self):
return B.calculate(self.value)
def main():
Aobj = A(value)
Aobj.calculate()

Python: pass whole self of class to init of new class

I have a class and a sub-class, I'd like to pass the whole of the self of the class to the sub-class. I can pass self over to the new class explicitly easily enough, e.g.
class foo:
def __init__(self, a, b):
self.a = a
self.b = b
self.c = 'foo'
def foo_method(self):
print('a foo method')
class bar(foo):
def __init__(self, foo_object):
self.a = foo_object.a
self.b = foo_object.b
self.c = foo_object.c
def bar_method(self):
print('a bar method')
foo_object = foo(a = 'a', b = 'b')
bar_object = bar(foo_object)
bar_object.a
Is there a more succinct way to pass these over? Something like:
class bar(foo):
def __init__(self, foo_object):
self = self.foo_object
Update:
Thanks https://stackoverflow.com/users/10104112/bastien-antoine, the following solution worked:
class bar(foo):
def __init__(self, foo_object):
self.__dict__ = foo_object.__dict__.copy()
def bar_method(self):
print('a bar method with ' + str(self.c))
Have you tried the copy builtins library?
Otherwise I think you can easily implement your own .copy() method that would copy the values from the old object __dict__ to the new one. Something like this:
class MyObject:
a = None
def set_default_values(self):
self.a = 1
def copy(self, old):
if type(self) == type(old):
self.__dict__ = old.__dict__.copy()
else:
raise TypeError('Wrong type')
if __name__ == "__main__":
obj_1 = MyObject()
print(obj_1.a)
obj_1.set_default_values()
print(obj_1.a)
obj_2 = MyObject()
print(obj_2.a)
obj_2.copy(obj_1)
print(obj_2.a)
Note that I've added a type checking to be sure that you copy attributes that would exist otherwise, but I think simply self.__dict__ = old.__dict__.copy() would work fine, thought you might end up with attributes you might not suppose to have in the new object.
Hope this helps!
I think that you can do that with
class bar(foo):
def __init__(self):
super(bar, self).__init__()
with this code, you ran the init function for the subclass

Use classmethod as default argument

If I do something like this:
class MyClass(object):
def __init__(self, a=MyClass.f):
self.a = a
#classmethod
def f():
print 'tump drump'
I get the following error:
NameError: name 'MyClass' is not defined
Obviously, I could do this:
class MyClass(object):
def __init__(self, a=None):
if a is None:
self.a = MyClass.f
else:
self.a = a
But is there a more elegant way to use a classmethod as default argument of a class method?
No, there isn't, because the functions are created before the class object is. There is not class to reference here, and the use of a sentinel (like None) is the correct way to do this.
Note that there is no need to use an else suite if you assign to a rather than self.a in the if suite:
class MyClass(object):
def __init__(self, a=None):
if a is None:
a = MyClass.f
self.a = a
or you could use a conditional expression:
class MyClass(object):
def __init__(self, a=None):
self.a = MyClass.f if a is None else a
or even:
class MyClass(object):
def __init__(self, a=None):
self.a = a or MyClass.f
if all you need to support is truthy objects (function objects always are 'true' in a boolean context, for example).

Call Python object's variable as a function without passing the calling object

I have a structure something like this:
def foobar():
print('FOOBAR!')
class SampleClass:
foo = foobar
def printfunc(self):
self.foo()
This doesn't work because the original foobar function can't handle self being passed to it -- it wasn't part of any class or object to begin with. Python won't let me add the #staticmethod decorator either.
I have no control over the definition of foobar, and I may have to override the value of foo in subclasses.
How can I call foo, without passing the object calling it?
Decorators are plain functions, you should be able to call staticmethod(foobar) explicitly in the class definition
class SampleClass:
foo = staticmethod(foobar)
def printfunc(self):
self.foo() # Prints 'FOOBAR!'
The approach from user2357112's comment seems to work, too:
def foobar():
print('FOOBAR!')
def foobaz():
print('FooBAZ!')
class SampleClass:
def foo(self):
foobar()
def printfunc(self):
self.foo()
class DerivedClass(SampleClass):
def foo(self):
foobaz()
sample = SampleClass()
sample.printfunc() # FOOBAR!
derived = DerivedClass()
derived.printfunc() # FooBAZ!
If return values shall make it through, you need return statements on all levels, though:
def foobar():
print('FOOBAR!')
return 'foo'
def foobaz():
print('FooBAZ!')
return 'baz'
class SampleClass:
def foo(self):
return foobar()
def printfunc(self):
return self.foo()
class DerivedClass(SampleClass):
def foo(self):
return foobaz()
sample = SampleClass()
s = sample.printfunc() # FOOBAR!
print(s) # foo
derived = DerivedClass()
d = derived.printfunc() # FooBAZ!
print(d) # baz

Categories