For example values from args i can extract like this
globals().update(vars(args))
Is it possible automatically create same properties fro class? Something like this
class SomeClass():
def __init__(self, args):
globals().update(vars(args))
exit(self.location)
I think you meant you want to update the attributes on the class; you can do so with:
class SomeClass():
def __init__(self, args):
vars(self).update(vars(args))
Demo:
>>> class Foo:
... def __init__(self):
... self.bar = 'baz'
...
>>> result = SomeClass(Foo())
>>> result.bar
'baz'
Related
Consider the following code:
class A(object):
def __init__(self):
pass
class B(object):
def __init__(self):
self.something = 'blue'
def get_something(self):
return self.something
class C(A,B):
def __init__(self):
super().__init__()
print(self.get_something())
and then do:
c = C()
which results in something like this:
AttributeError: 'C' object has no attribute 'something'
I suppose this happens due to the constructor of B not being called when using super(). Is there a way to achieve the correct behavior with Python 3?
Superclasses should use super if their subclasses do. If you add the super().__init__() line into A and B your example should work again.
Check the method resolution order of C:
>>> C.mro()
[__main__.C, __main__.A, __main__.B, builtins.object]
This article should clear things up.
As others have mentioned, the method resolution order is key here. If you want to call multiple superclass constructors, then you will have to call them directly.
class A(object):
def __init__(self):
pass
class B(object):
def __init__(self):
self.something = 'blue'
def get_something(self):
return self.something
class C(A,B):
def __init__(self):
A.__init__(self)
B.__init__(self)
print(self.get_something())
How do I access *args variable name(s) in __init__ method?
E.g.
class Parent:
def __init__(self, *args):
# How to access *args variable names here?
# In this example: foo, bar
pass
class Child(Parent):
def __init__(self, foo, bar):
super().__init__(foo, bar)
Inspired by OP's comment, maybe you could do something like
class Parent:
def __init__(self, *args):
self.child_varnames = type(self).__init__.__code__.co_varnames[1:]
class Child(Parent):
def __init__(self, foo, bar):
super().__init__(foo, bar)
In my tests, I get
>>> c = Child(1, 2)
>>> c.child_varnames
('foo', 'bar')
I wonder if we can call variable initiated in self in class method. For example:
class ABC():
def method1(self):
self.var1 = '123'
#classmethod
def callvar1(cls):
'''print var1'''
I want to achieve the same output like this:
class ABC():
var1 = '123'
def method1(self):
self.var1 = '123'
#classmethod
def callvar1(cls):
print(cls.var1)
How can I access self.var1 in callvar1?
Since callvar1 is a class method, it does not have access to self. This is because the method is not tied to a specific instance of the class, but rather to the class itself. Therefore, when you call the method, it does not know which instance you are referring to. As you did in the second block of the code, you must pass the object whose var1 you would like to print to the function.
Your other option would be to not make it a class method.
Class methods are bound to the class itself rather than a particular instance of it so if you're trying to access self.var1 (an instance variable) inside the class method you're not going to have much fun.
Your best option is to simply make the method not a class method (depending on your use case):
>>> class ABC():
... var1 = '123'
... def method1(self):
... self.var1 = '123'
... def callvar1(self):
... print(self.var1)
...
>>> b = ABC()
>>> b.callvar1()
123
Although another option is to pass an instance of the class to the class method:
>>> class ABC():
... var1 = '123'
... def method1(self):
... self.var1 = '123'
... #classmethod
... def callvar1(cls, inst):
... print(inst.var1)
...
>>> b = ABC()
>>> ABC.callvar1(b)
123
Use the self keyword to access members of the class.
class ABC():
var1 = '123'
def method1(self):
self.var1 = '123'
#classmethod
def callvar1(self):
print(self.var1)
Let's say I have this:
from PySide2 import QtWidgets
class MyClass(object):
def __init__(self, parent=None):
self.class_variable = QtWidgets.QWidget()
class_instance = MyClass()
variable = class_instance.class_variable
class_instance_returned = mystery_method(variable) # How to make this return class_instance?
How should I define mystery_method so that it would return the class_instance instance?
The real-world case I have is that I'm sending a QWidget which I'm using as a base instance for .ui file loading into a function. Inside this function I need to figure out which class instance it belongs to.
Python 2.7
class MyClass(object):
def foo():
return 'bar'
instance = MyClass()
def mystery_method(method):
return method.im_self.__class__
print mystery_method(instance.foo)
Python 3
class MyClass(object):
def foo():
return 'bar'
instance = MyClass()
def mystery_method(method):
return method.__self__.__class__
print mystery_method(instance.foo)
EDIT
After the OP was edited:
class ParentClass():
def foo():
return 'bar'
class MyClass(object):
def __init__(self, parent=None):
self.instance_attribute = ParentClass()
def mystery_method(method):
return method.__class__
class_instance = MyClass()
print mystery_method(class_instance.instance_attribute)
One way would we to define foo as a custom property that returns both its value and the related instance when its value is fetched:
from collections import namedtuple
class Prop(object):
def __init__(self, val):
self.val = val
def __get__(self, instance, type):
return namedtuple('Prop', ('value', 'instance'))(self.val, instance)
def __set__(self, instance, val):
self.val = val
class MyClass(object):
foo = Prop('bar')
Now in your program you can explicitly use its value and the related instance using foo's value and instance attributes respectively.
Demo:
>>> instance = MyClass()
>>> instance.foo
Prop(value='bar', instance=<__main__.MyClass object at 0x10effbcd0>)
>>> instance.foo.value
'bar'
>>> instance.foo.instance
<__main__.MyClass object at 0x10effbcd0>
In general you cannot (at least not without a lot of searching through all the objects in the system) but if all you want is to find which instances of a class match a particular value then it's fairly easy.
You can create a set of all instances and iterate over them to find what you need.
from weakref import WeakSet
class MyClass(object):
_instances = WeakSet()
def __init__(self, foo):
self._instances.add(self)
self.foo = foo
#classmethod
def findFoo(cls, foo):
return [instance for instance in cls._instances if instance.foo == foo]
>>> instance1 = MyClass('bar')
>>> instance2 = MyClass('baz')
>>> MyClass.findFoo('baz')
[<__main__.MyClass object at 0x7f6723308f50>]
>>> MyClass.findFoo('bar')
[<__main__.MyClass object at 0x7f6723308c50>]
Note that deleting the object won't remove it immediately, it may not go until garbage collected:
>>> del instance1
>>> MyClass.findFoo('bar')
[<__main__.MyClass object at 0x7f6723308c50>]
>>> import gc
>>> gc.collect()
16
>>> MyClass.findFoo('bar')
[]
However in general you would be better to keep the reference to the original object hanging around and just use that.
Also, note that you cannot reliably tell which instance holds 'bar' if it is stored in more than one object: they could be the same 'bar' or they could be different ones, and whether they are the same or different is an implementation detail.
I have a class like this:
class MyClass(object):
def f_1(self,x):
return foo(x, self.property_1)
def f_2(self,x):
return foo(x, self.property_2)
The idea is that multiple functions f_n have a common structure, but depend on different properties property_n of the class.
I look for a more compact way to define those f_n in the __init__? I think of something like
class MyClass(object):
def __init__(self):
self.f_1 = self.construct_function(self.property_1)
self.f_2 = self.construct_function(self.property_2)
def construct_function(self, property):
# ???
That is what I have in mind, but I dont know how to define this construct_function. It is important that 'property' is of a point-by-value type.
Edit:
I simplified Martijn's very good answer to this solution, which works fine:
def construct_function(property_name):
def f_n(self, x):
return foo(x, getattr(self, property_name))
return f_n
class MyClass2(object):
f_1 = construct_function('property_1')
f_2 = construct_function('property_2')
Just wanted to mention it here, as multiline comments are not allowed...
If you want to generate these methods per class, use a class decorator:
def property_functions(**properties):
def construct_method(prop):
def f_n(self):
return foo(getattr(self, prop))
return f_n
def class_decorator(cls):
for name, prop in properties.iteritems():
setattr(cls, name, construct_method(prop))
return cls
return class_decorator
then use it like:
#property_functions(f_1='property_1', f_2='property_2')
class MyClass(object):
property_1 = 'foo'
property_2 = 'bar'
Demonstration:
>>> def foo(value): print value
...
>>> #property_functions(f_1='property_1', f_2='property_2')
... class MyClass(object):
... property_1 = 'foo'
... property_2 = 'bar'
...
>>> mc = MyClass()
>>> mc.f_1()
foo
>>> mc.f_2()
bar
You can have a look at getattr or getattribute . They allow you dynamically create and reference attributes. For ex
It works something like this:
class foo:
def __init__(self):
self.a = "a"
def __getattr__(self, attribute):
return "You asked for %s, but I'm giving you default" % attribute
>>> bar = foo()
>>> bar.a
'a'
>>> bar.b
"You asked for b, but I'm giving you default"
>>> getattr(bar, "a")
'a'
>>> getattr(bar, "b")
"You asked for b, but I'm giving you default"