Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
ashawkey committed Dec 12, 2023
1 parent 7c2f29a commit f76837b
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 1 deletion.
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
[kiui](https://kiui.moe/)'s notebook.

## Recent Updates
- [monky_patch.md](python\monky_patch/) <div style="text-align: right">2023-12-12 18:58:16.041742</div>
- [camera_intrinsics_exintrics.md](vision\camera_intrinsics_exintrics/) <div style="text-align: right">2023-12-11 10:48:44.821914</div>
- [set_usual_apps_proxy.md](web\proxy\set_usual_apps_proxy/) <div style="text-align: right">2023-12-08 16:21:56.252977</div>
- [slurm.md](linux\slurm/) <div style="text-align: right">2023-12-07 15:20:34.127883</div>
Expand All @@ -23,4 +24,3 @@
- [git_tricks.md](linux\git_tricks/) <div style="text-align: right">2023-11-18 11:04:41.502742</div>
- [trojan.md](web\proxy\trojan/) <div style="text-align: right">2023-11-17 09:55:15.367723</div>
- [bash.md](linux\bash/) <div style="text-align: right">2023-11-17 09:19:57.540734</div>
- [datetime.md](python\datetime/) <div style="text-align: right">2023-11-06 14:25:24.795182</div>
125 changes: 125 additions & 0 deletions docs/python/monky_patch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
## Monkey patch a method



To patch the `forward` of a `nn.Module`, **define a closure** that keeps temporary variables and returns your new `forward`:

```python
import torch.nn as nn

class A(nn.Module):
def __init__(self, name):
super().__init__()
self.name = name

def forward(self):
print(f'original forward of {self.name}')

a = A('a')
b = A('b')

for name, m in zip(['a', 'b'], [a, b]):

def make_forward():
# record the current name in closure !
cur_name = name
def _forward():
print(f'patched forward of {cur_name}')
return _forward

m.forward = make_forward()

a()
b()
```

Output:

```
patched forward of a
patched forward of b
```



However, you cannot patch magic methods like `__call__` by this:

```python
class A:
def __init__(self, name):
super().__init__()
self.name = name

def __call__(self):
print(f'original forward of {self.name}')

a = A('a')
b = A('b')

for name, m in zip(['a', 'b'], [a, b]):

def make_call():
# record the current name in closure !
cur_name = name
def _call():
print(f'patched forward of {cur_name}')
return _call

m.__call__ = make_call()

a()
b()
```

Output:

```
original forward of a
original forward of b
```

This is because `__call__` is looked-up with respect to the class instead of instance, so we are still calling the original `__call__`.

We have to patch the class to make this work, and **cast instances to the derived class**:

```python
class A:
def __init__(self, name):
super().__init__()
self.name = name

def __call__(self):
print(f'original forward of {self.name}')

a = A('a')
b = A('b')

# a derived class that redirect __call__ to our patched call
class B(A):
def __call__(self):
self.patched_call()

for name, m in zip(['a', 'b'], [a, b]):

def make_call():
# record the current name in closure !
cur_name = name
def _call():
print(f'patched forward of {cur_name}')

return _call

m.__class__ = B # magic cast!
m.patched_call = make_call()

a()
b()
```

Output:

```
patched forward of a
patched forward of b
```

0 comments on commit f76837b

Please sign in to comment.