Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #93044 > unrolled thread
| Started by | Tim <jtim.arnold@gmail.com> |
|---|---|
| First post | 2015-06-23 11:32 -0700 |
| Last post | 2015-06-23 13:59 -0700 |
| Articles | 3 — 3 participants |
Back to article view | Back to comp.lang.python
method returns object reference Tim <jtim.arnold@gmail.com> - 2015-06-23 11:32 -0700
Re: method returns object reference Ian Kelly <ian.g.kelly@gmail.com> - 2015-06-23 13:30 -0600
Re: method returns object reference Ned Batchelder <ned@nedbatchelder.com> - 2015-06-23 13:59 -0700
| From | Tim <jtim.arnold@gmail.com> |
|---|---|
| Date | 2015-06-23 11:32 -0700 |
| Subject | method returns object reference |
| Message-ID | <109aafce-613c-4d6c-9f78-4bbe424f5901@googlegroups.com> |
I spent a while finding this problem which looks something like the old "mutable default argument" problem. http://docs.python-guide.org/en/latest/writing/gotchas/#mutable-default-arguments
I'm not crystal clear on the details, but once I found it, the fix was easy.
I'm posting here just because I thought it was interesting.
The situation is that I have a Worker() which has a Client().
The worker queries the client; client returns its self.response
worker manipulates that response. Now client's response has same changes.
The code below prints the following two lines, showing how the 'newkey' is now inside the Client response, even though it was set in the worker. This must be bad practice! In my real code, the response is no longer an instance variable, which fixed the problem. It never had any business being bound to the client anyway.
output:
[('text', 'first thing')]
[('text', 'second thing'), ('newkey', 'my new value')]
class Client(object):
def __init__(self):
self.response = dict()
def query(self, text):
self.response['text'] = text
print self.response.items()
return self.response
class Worker(object):
def __init__(self):
self.client = Client()
def work(self, expression):
data = self.client.query(expression)
data['newkey'] = 'my new value'
if __name__ == '__main__':
t = Worker()
t.work('first thing')
t.work('second thing')
[toc] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2015-06-23 13:30 -0600 |
| Message-ID | <mailman.732.1435087895.13271.python-list@python.org> |
| In reply to | #93044 |
On Tue, Jun 23, 2015 at 12:32 PM, Tim <jtim.arnold@gmail.com> wrote: > The code below prints the following two lines, showing how the 'newkey' is now inside the Client response, even though it was set in the worker. This must be bad practice! In my real code, the response is no longer an instance variable, which fixed the problem. It never had any business being bound to the client anyway. I agree. There may be reasons why the client would want to hold onto the response, e.g. caching, but there are none evident in the code you posted. What it *shouldn't* do if it's going to hold on to state like that is share it with external code without at least a contract defining allowed mutations. If the consumer can't reasonably be expected not to modify the shared state, then it should be copied, not shared.
[toc] | [prev] | [next] | [standalone]
| From | Ned Batchelder <ned@nedbatchelder.com> |
|---|---|
| Date | 2015-06-23 13:59 -0700 |
| Message-ID | <99d81f4b-fbdb-4309-9bd7-f278e0119079@googlegroups.com> |
| In reply to | #93044 |
On Tuesday, June 23, 2015 at 2:32:55 PM UTC-4, Tim wrote:
> I spent a while finding this problem which looks something like the old "mutable default argument" problem. http://docs.python-guide.org/en/latest/writing/gotchas/#mutable-default-arguments
>
> I'm not crystal clear on the details, but once I found it, the fix was easy.
> I'm posting here just because I thought it was interesting.
>
> The situation is that I have a Worker() which has a Client().
> The worker queries the client; client returns its self.response
> worker manipulates that response. Now client's response has same changes.
Assignment in Python never makes a copy, it only makes a new name refer to
an existing value. This talk covers the details in depth:
http://nedbatchelder.com/text/names1.html
--Ned.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web