user975135
user975135

Reputation:

can one function be overwritten by calling another?

Let's say you have functions a and b. Can you, by calling function a, replace function b with another function?

I know you can do b=a(b), but can you change b with just doing a(b)?

Upvotes: 1

Views: 99

Answers (5)

Wooble
Wooble

Reputation: 89927

You can replace the code object of b with another function's code:

>>> def b():
...    print 'b'
...
>>> def a():
...    print 'a'
...
>>> def c(f):
...    f.__code__ = a.__code__ # func_code instead of __code__ for py 2.5 and earlier
...
>>> c(b)
>>> b()
a

Although this is almost certainly a sign you're thinking of whatever problem you're trying to solve in the wrong way.

Upvotes: 4

Nitzle
Nitzle

Reputation: 2477

You could use global to accomplish something like this.

>>> def a():
...     global b
...     def b():
...         print "New Function B"
>>> def b():
...     print "Function B"
...
...
>>> b()
Function B
>>> a()
>>> b()
New Function B
>>>

If you don't know which method you're replacing, you can use function.func_code to replace one function's code with another.

>>> def change(old_func, new_func):
...     old_func.func_code = new_func.func_code
...
>>> def a():
...     print "Function A"
...
>>> def b():
...     print "Function B"
...
>>> def c():
...     print "Function C"
...
>>>
>>> change(a, b)
>>> a()
Function B
>>> change(a, c)
>>> a()
Function C
>>>

Upvotes: 2

bikeshedder
bikeshedder

Reputation: 7487

I'm not sure what you are aiming for, but yes, you can do that:

>>> def a():
...     global b
...     b = a
...     return 'a'
... 
>>> def b():
...     return 'b'
... 
>>> b()
'b'
>>> a()
'a'
>>> b()
'a'
>>> def c(f):

What if I don't know I'm overwriting b beforehand?In other words, if I want to pass b as an argument to a

>>> def c(f):
...     global b
...     b = f
...     return 'c'
... 
>>> def d():
...     return 'd'
... 
>>> b()
'a'
>>> c(d)
'c'
>>> b()
'd'
>>> c(a)
'c'
>>> b()
'a'

Upvotes: 1

isedev
isedev

Reputation: 19611

Functions and methods are attributes of modules and classes respectively. So you can modify the required attribute to point to another function.

>>> __name__
'__main__'
>>> def a():
...     print 'a'
... 
>>> def b():
...     print 'b'
... 
>>> import sys
>>> sys.modules['__main__'].b = a
>>> b()
a

For a class:

>>> class A(object):
...     def a(self):
...             print 'a'
...     def b(self):
...             print 'b'
... 
>>> A.b = A.a
>>> x = A()
>>> x.b()
a

And if you have a variable holding the name to replace, then use setattr, for example:

setattr(sys.modules['__main__'],'b',a)
setattr(A,'b',A.a)

Just replace the string ('b') with your variable.

Not sure why you would want to though? It will make for confusing code.

Upvotes: 4

jeffknupp
jeffknupp

Reputation: 6274

You can do it easily like this

def a(func):
    globals()[func] = c

def b():
    print('b')

def c():
    print('c')

a()
b()
>>> c

Upvotes: 1

Related Questions