Просмотр исходного кода

Finish dictionaries, lists, and tuples.

master
Ben Kurtovic 9 лет назад
Родитель
Сommit
56e3a4a913
1 измененных файлов: 87 добавлений и 8 удалений
  1. +87
    -8
      _drafts/python-object-replacement.md

+ 87
- 8
_drafts/python-object-replacement.md Просмотреть файл

@@ -565,26 +565,105 @@ should work for any case where `a` is in a dictionary-like object.

## Handling different reference types

We'll continue by wrapping this code up in a nice function:
We'll continue by wrapping this code up in a nice function, which we will
expand as we go:

{% highlight python %}

import guppy
from guppy.heapy import Path

hp = guppy.hpy()

def replace(old, new):
pass
for path in hp.iso(old).pathsin:
relation = path.path[1]
if isinstance(relation, Path.R_INDEXVAL):
path.src.theone[relation.r] = new

{% endhighlight %}

### Dictionaries
### Dictionaries, lists, and tuples

As noted above, this is versatile to handle many dictionary-like situations,
including `__dict__`, which means we already know how to replace object
attributes:

{% highlight pycon %}

>>> a, b = A(), B()
>>>
>>> class X(object):
... pass
...
>>> X.cattr = a
>>> x = X()
>>> x.iattr = a
>>> d1 = {1: a}
>>> d2 = [{1: {0: ("foo", "bar", {"a": a, "b": b})}}]
>>>
>>> replace(a, b)
>>>
>>> print a
<__main__.B object at 0x1042b9910>
>>> print X.cattr
<__main__.B object at 0x1042b9910>
>>> print x.iattr
<__main__.B object at 0x1042b9910>
>>> print d1[1]
<__main__.B object at 0x1042b9910>
>>> print d2[0][1][0][2]["a"]
<__main__.B object at 0x1042b9910>

{% endhighlight %}

Lists can be handled exactly the same as dictionaries, although the keys in
this case (i.e., `relation.r`) will always be integers.

dicts, class attributes via `__dict__`, locals()
{% highlight pycon %}

### Lists
>>> a, b = A(), B()
>>> L = [0, 1, 2, a, b]
>>> print L
[0, 1, 2, <__main__.A object at 0x104598950>, <__main__.B object at 0x104598910>]
>>> replace(a, b)
>>> print L
[0, 1, 2, <__main__.B object at 0x104598910>, <__main__.B object at 0x104598910>]

simple replacement
{% endhighlight %}

### Tuples
Tuples are interesting. We can't modify them directly because they're
immutable, but we _can_ create a new tuple with the new value, and then replace
that tuple just like we replaced our original object:

recursively replace parent since immutable
{% highlight python %}

# Meanwhile, in replace()...
if isinstance(relation, Path.R_INDEXVAL):
source = path.src.theone
if isinstance(source, tuple):
temp = list(source)
temp[relation.r] = new
replace(source, tuple(temp))
else:
source[relation.r] = new

{% endhighlight %}

As a result:

{% highlight pycon %}

>>> a, b = A(), B()
>>> t1 = (0, 1, 2, a)
>>> t2 = (0, (1, (2, (3, (4, (5, (a,)))))))
>>> replace(a, b)
>>> print t1
(0, 1, 2, <__main__.B object at 0x104598e50>)
>>> print t2
(0, (1, (2, (3, (4, (5, (<__main__.B object at 0x104598e50>,)))))))

{% endhighlight %}

### Bound methods



Загрузка…
Отмена
Сохранить