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.
Related
This question already has an answer here:
What does calling self within a class do?
(1 answer)
Closed 7 months ago.
Here is part of code from mmcv (mmcv/runner/base_module.py).
I don't understand how does self(**data) works.
class BaseDetector(BaseModule, metaclass=ABCMeta):
"""Base class for detectors."""
# ...
def train_step(self, data, optimizer):
losses = self(**data)
loss, log_vars = self._parse_losses(losses)
outputs = dict(
loss=loss, log_vars=log_vars, num_samples=len(data['img_metas']))
return outputs
class BaseModule(nn.Module, metaclass=ABCMeta):
def __init__(self, init_cfg: Optional[dict] = None):
# ...
Tried to find some function like __call__ in the parent class, but it seems not the right direction to go.
Could any one explain why self could be used as a function?
This is nothing specific to PyTorch but rather to how Python works.
"Calling" an object is equivalent to calling a special Python function named __call__. Essentially, this is the function which implements the call behaviour. In your case self(**data) will call BaseDetector's __call__ function which has most probably been implemented by one of the parent classes.
Here is a minimal example to understand this behaviour:
class A():
def __call__(self):
return 'hello'
class B(A):
def foo(self):
return self() + ' world'
Initialize a new object from B:
b = B()
Then let us call the foo method on b:
>>> b.foo()
'hello world'
This function has been calling b() i.e. b.__call__():
>>> b() # same as b.__call__()
'hello'
As an additional note, you can explicitly call the implementation of the parent class. This is useful when you need to overload the original implementation in your child's class.
It is done by calling super:
class A():
def __call__(self):
return 'hello'
class B(A):
def __call__(self):
# calling self() here would create an infinite recursion loop
return super().__call__() + ' world'
Then you can call an instance of B the same way:
>>> b = B()
>>> b()
'hello world'
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.
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.
I know how fierce the SO community is so I'll try my best to keep the question minimal, complete and verifiable.
What I simply want to know is can monkey patching be used to replace the definition of an existing function?
for example:
class A():
def foo():
print '2'
def foo():
print '5'
A.foo = foo
This way doesn't seem to work also as to why I don't just add a new function instead of replacing an existing one, I call these functions in other classes and it is my understanding that monkey patching adds those functions at run-time and I need my python code to run on an Apache spark server which throws an error deeming the calls to that function unreferenced.
So please be nice and help me out or suggest a work around.
Thanks.
Edit: The goal of the code is to print 5 when A.foo is called.
Your only problem is that you aren't defining foo correctly in the first place. It needs to take an explicit argument for the instance calling it.
class A(object):
def __init__(self)
self.x = 2
def foo(self):
print(self.x)
def foo(this):
print(this.x + 3)
A.foo = foo
a = A()
a.foo() # outputs 5 in Python 2 and Python 3
In a very real sense, monkey patching is how classes are created in the first place. A class statement is almost just syntactic sugar for the following code:
def foo(self):
print(self.x)
A = type('A', (object,), {'foo': foo})
del foo
It's not too much of a simplification to image the definition of type being something like
def type(name, bases, d):
new_class = magic_function_to_make_a_class()
new_class.name = name
new_class.bases = bases
for k, v in d.items():
setattr(new_class, k, v)
return new_class
I hope I understand what you are trying to do here. This would work in Python 3:
class A():
def foo():
print('2')
def foo():
A.foo = lambda: print('5')
A.foo() # Print '2'
foo() # Assign the new method
A.foo() # Prints '5'
In Python 2 however there are several caveats.
print is not a method as it is in Python 3 (see here: Why doesn't print work in a lambda?)
You can't just call unbound messages (see here: In Python, can you call an instance method of class A, but pass in an instance of class B?)
So you have to do it like this:
from __future__ import print_function
class A():
def foo():
print('2')
def foo():
A.foo = lambda: print('5')
A.foo.__func__() # Print '2'
foo() # Assign the new method
A.foo.__func__() # Prints '5'
Edit:
After seeing your question in the comment I think you actually want something different. Which is this:
class A():
def foo(self):
print '2'
def foo(self):
print '5'
a = A()
a.foo() # Print '2'
A.foo = foo # Assign the new method
a.foo() # Prints '5'
This works just fine in Python 2.
The self is a reference to the current instance the method is bound to. It is not used when you just call something like print which access any properties or methods attached to that instance. But for a different case please have a look at the following example:
class A():
msg = "Some message"
def foo(self):
print self.msg
def bar(self):
self.msg = "Some other message"
a = A()
a.foo() # Print old msg
A.bar = bar # Assign the new method
a.bar() # Assigns new message
a.foo() # Prints new message
Also as chepner points out in a comment under his post:
The name self isn't special; it's just a convention. You could use
this if you really wanted to, and it doesn't need to be the same name
in both functions defined here. What is important is that the first
argument to a function used as an instance method will be a reference
to the calling object. a.foo() is almost exactly the same as A.foo(a)
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.