Instance attribute as default argument [duplicate] - python

This question already has answers here:
How to pass a default argument value of an instance member to a method?
(6 answers)
Closed 4 years ago.
I use Python 3 and I have small problem with kwargs. Is it possible to use instance attributes as a default argument value? I mean something like this:
class foo:
def __init__(self, a,b):
self.a = a
self.b = b
def setNewA(self, a=self.a):
print(a)
But I've got an error:
NameError: name 'self' is not defined
If I use class name I've got:
AttributeError: type object 'foo' has no attribute 'a'
I know that the other method is to use something like this:
def setNewA(self, a=None):
a = a or self.a
print(a)
But maybe there is some way to do it?

Not sure if this fits your use-case, but how about this?
>>> class foo:
... b = 1
...
... def setNewA(self, a=b):
... print(a)
>>>
>>> f = foo()
>>> f.setNewA()
1
>>> f.setNewA(2)
2

Related

I can't use a function into a class. How can I resolve this? [duplicate]

This question already has answers here:
How can I call a function within a class?
(2 answers)
Closed 4 years ago.
I am relatively new to python and i am experiencing some issues with namespacing.
class a:
def abc(self):
print "haha"
def test(self):
abc()
b = a()
b.test() #throws an error of abc is not defined. cannot explain why is this so
Since test() doesn't know who is abc, that msg NameError: global name 'abc' is not defined you see should happen when you invoke b.test() (calling b.abc() is fine), change it to:
class a:
def abc(self):
print "haha"
def test(self):
self.abc()
# abc()
b = a()
b.abc() # 'haha' is printed
b.test() # 'haha' is printed
In order to call method from the same class, you need the self keyword.
class a:
def abc(self):
print "haha"
def test(self):
self.abc() // will look for abc method in 'a' class
Without the self keyword, python is looking for the abc method in the global scope, that is why you are getting this error.

Python: How to create a class object using Importlib [duplicate]

This question already has answers here:
TypeError: Missing 1 required positional argument: 'self'
(8 answers)
Closed 2 years ago.
I know a similar question has been asked/answered several times. But please do read on ..
I am trying to create a Class from a string value as described in "Convert string to Python Class Object" in Python 3.6.
utils.py
class Foo(object):
def __init__(self):
print("In the constructor of Foo")
def What(self):
print("so what ... ")
class FooParam(object):
def __init__(self, v):
self.value = v
print("In the constructor of FooParam")
def What(self):
print("Value=" % self.value)
print("So what now ...")
welcome.py
def TEST1():
m = importlib.import_module("utils")
c = getattr(m, "Foo")
c.What()
if __name__ == '__main__':
TEST1()
Error
TypeError: What() missing 1 required positional argument: 'self'
So what am I doing wrong ?
Also how can I create an object of "FooParam" and pass a value to the constructor.
Once you import the module just access with the variable you stored imported module:
m = importlib.import_module("utils")
foo = m.Foo()
foo.What()
import_module performs the same steps as import.
This c = getattr(m, "Foo") line of code is equivalent f = Foo so that means you are not creating an instance instead you are getting a reference to that class.
I suspect that c is the class Foo but not an instance of the class.
This is equivalent to simply calling
Foo.what()
Which is why self is not defined!
Whereas what you want is to create an instance of the class (giving it a 'self' property), then call its method, i.e.
foo_instance = Foo()
foo_instance.What()
so try replacing c.What() with..
foo_instance = c()
foo_instance.What()
for FooParam:
#import the class FooParam
c = getattr(m, "FooParam")
#create an instance of the class, initializing its values (and self)
fooparam_instance = c(3.14)
#call its method!
fooparam_instance.What()
on the whole I would rename the variable c, to something like foo_import and fooparam_import respectively :)

How can I use getattr to access an attribute within an attribute? [duplicate]

This question already has answers here:
Python - getattr and concatenation
(2 answers)
Closed 8 years ago.
What I have is a value found in:
value.number.odd = 7
number.odd is an input by the user, in x.
and so if x='number.odd', I was hoping that:
getattr(value, x)
would display what value.number.odd would, but it doesn't. Instead I get:
AttributeError: missing attribute number.odd
EDIT:
Input x can also be something like X='number', or 'number.negative.prime'
You can use reduce for this (functools.reduce in Python 3.x):
reduce(getattr, x.split('.'), value)
See a demonstration below:
>>> class A:
... def __init__(self):
... self.odd = 7
...
>>> class B:
... def __init__(self):
... self.number = A()
...
>>> value = B()
>>> value.number.odd
7
>>> x = 'number.odd'
>>> reduce(getattr, x.split('.'), value)
7
>>>
getattr(getattr(value, 'number'), 'odd')
Or taken from Python - getattr and concatenation by Cat Plus Plus
def getattr_deep(start, attr):
obj = start
for part in attr.split('.'):
obj = getattr(obj, part)
return obj
getattr_deep(foo, 'A.bar')

How to get class name when there is attribute attached? [duplicate]

This question already has answers here:
Get class that defined method
(8 answers)
Closed 8 years ago.
For example,
I want to return 'ClassName' from the following:
ClassName().MethodName
When I try:
ClassName().MethodName.__class__.__name__
>>instancemethod
or when I try:
ClassName().MethodName.__name__
>>MethodName
Perhaps this isn't possible, so would there be a way to turn ClassName().MethodName to ClassName(), so I could then run this, which is what I want:
ClassName().__class__.__name__
>> ClassName
The information you want is in the im_class attribute of the bound method object:
>>> class Foo():
... def bar():
... pass
...
>>> m = Foo().bar
>>> m.im_class
<class __main__.Foo at 0x1073bda78>
Like so:
class Foo(object):
def MethodName():
pass
print type(Foo()).__name__
# Foo
Or,
foo=Foo()
print type(foo).__name__
# Foo
(Note -- that only works on new style classes, not legacy classes. It obviously only works if you know what to call to instantiate the class)
If all you have is reference to a method, you can use inspect (Thx Alex Martelli):
import inspect
def get_class_from_method(meth):
for cls in inspect.getmro(meth.im_class):
if meth.__name__ in cls.__dict__: return cls
return None
>>> mn=Foo().MethodName
>>> get_class_from_method(mn).__name__
Foo
Or, for a user defined method, you can do:
>>> mn.im_class.__name__
Foo

How is Python class attribute being set without actually being set? [duplicate]

This question already has answers here:
"Least Astonishment" and the Mutable Default Argument
(33 answers)
Closed 8 years ago.
Can someone please explain what's going on in the following? Why on earth does object b have the value of object a's list?
class Test:
def __init__(self, A = []):
self.A = A
def __str__(self):
return str(self.A)
def mutate_A():
a = Test()
a.A.append(1)
return a
def problem_here():
a = mutate_A()
b = Test()
print b # why does this print [1] in python 2.7
problem_here()
Please let me know if I am being unclear or if more information is needed. Thank you.
Because in python, the default arguments are evaluated only once (when the function is defined). Therefore, all instances of the class use the same list A
If however, you want each instance to have its own list, then you should do:
def __init__(self):
self.A = []
>>> a = mutate_A()
>>> b = Test()
>>> print b
[]

Categories