Why can I reassign dict.update but not dict.__setitem__Why doesn't this python assignment work as obviously expected?How can I safely create a nested directory?How can I remove a trailing newline?Python join: why is it string.join(list) instead of list.join(string)?How can I make a time delay in Python?Should I use 'has_key()' or 'in' on Python dicts?How can I count the occurrences of a list item?Why can't Python parse this JSON data?Why is reading lines from stdin much slower in C++ than Python?Why dict.get(key) instead of dict[key]?Why is “1000000000000000 in range(1000000000000001)” so fast in Python 3?
What is this little owl-like bird?
Short story about Nobel Prize winning scientists that drop out when they realise they were incorrect
Why return a static pointer instead of an out parameter?
How to tell someone I'd like to become friends without letting them think I'm romantically interested in them?
Disc brake equipped time trial bikes in grand tour
Why do we need common sense in AI?
LED glows slightly during soldering
Should disabled buttons give feedback when clicked?
Is "De qui parles-tu" (for example) as formal as it is in English, or is it normal for the French to casually say that
What does the phrase "head down the rat's hole" mean here?
Received a dinner invitation through my employer's email, is it ok to attend?
When I press the space bar it deletes the letters after it
Transit visa for 5 hours layover in Chicago (USA)
Data Encryption by Application vs Data Encryption in Database
Can I completely remove lens distortion from any image?
Singleton with an object which throws in the ctor - accessing again?
What happens to unproductive professors?
How are mathematicians paid to do research?
How to know if blackberries are safe to eat
What are the original Russian words for a prostitute?
Confirming the Identity of a (Friendly) Reviewer After the Reviews
What is this red spacesuit made out of, and why is it red?
Would it be appropriate to sand a floor between coats of poly with a handheld orbital sander?
Does throwing a penny at a train stop the train?
Why can I reassign dict.update but not dict.__setitem__
Why doesn't this python assignment work as obviously expected?How can I safely create a nested directory?How can I remove a trailing newline?Python join: why is it string.join(list) instead of list.join(string)?How can I make a time delay in Python?Should I use 'has_key()' or 'in' on Python dicts?How can I count the occurrences of a list item?Why can't Python parse this JSON data?Why is reading lines from stdin much slower in C++ than Python?Why dict.get(key) instead of dict[key]?Why is “1000000000000000 in range(1000000000000001)” so fast in Python 3?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I'm trying to modify a third-party dict class to make it immutable after a certain point.
With most classes, I can assign to method slots to modify behavior.
However, this doesn't seem possible with all methods in all classes. In particular for dict, I can reassign update, but not __setitem__.
Why? How are they different?
For example:
class Freezable(object):
def _not_modifiable(self, *args, **kw):
raise NotImplementedError()
def freeze(self):
"""
Disallow mutating methods from now on.
"""
print "FREEZE"
self.__setitem__ = self._not_modifiable
self.update = self._not_modifiable
# ... others
return self
class MyDict(dict, Freezable):
pass
d = MyDict()
d.freeze()
print d.__setitem__ # <bound method MyDict._not_modifiable of >
d[2] = 3 # no error -- this is incorrect.
d.update(4:5) # raise NotImplementedError
python
add a comment |
I'm trying to modify a third-party dict class to make it immutable after a certain point.
With most classes, I can assign to method slots to modify behavior.
However, this doesn't seem possible with all methods in all classes. In particular for dict, I can reassign update, but not __setitem__.
Why? How are they different?
For example:
class Freezable(object):
def _not_modifiable(self, *args, **kw):
raise NotImplementedError()
def freeze(self):
"""
Disallow mutating methods from now on.
"""
print "FREEZE"
self.__setitem__ = self._not_modifiable
self.update = self._not_modifiable
# ... others
return self
class MyDict(dict, Freezable):
pass
d = MyDict()
d.freeze()
print d.__setitem__ # <bound method MyDict._not_modifiable of >
d[2] = 3 # no error -- this is incorrect.
d.update(4:5) # raise NotImplementedError
python
1
__setitem__is a "special" method and is looked up using the class ofself, not in the instance's__dict__.
– martineau
Mar 26 at 1:14
Why isn’t update the same?
– user48956
Mar 26 at 1:15
updatedoesn't begin and end with double underscores (aka "dunder"), so no, it's not "special". Here's something about them in the documentation — notice there's noupdate— also see "special method" in the glossary.
– martineau
Mar 26 at 1:18
You may be interested in this stackoverflow.com/questions/47915937/…
– Jacques Gaudin
Mar 26 at 1:30
add a comment |
I'm trying to modify a third-party dict class to make it immutable after a certain point.
With most classes, I can assign to method slots to modify behavior.
However, this doesn't seem possible with all methods in all classes. In particular for dict, I can reassign update, but not __setitem__.
Why? How are they different?
For example:
class Freezable(object):
def _not_modifiable(self, *args, **kw):
raise NotImplementedError()
def freeze(self):
"""
Disallow mutating methods from now on.
"""
print "FREEZE"
self.__setitem__ = self._not_modifiable
self.update = self._not_modifiable
# ... others
return self
class MyDict(dict, Freezable):
pass
d = MyDict()
d.freeze()
print d.__setitem__ # <bound method MyDict._not_modifiable of >
d[2] = 3 # no error -- this is incorrect.
d.update(4:5) # raise NotImplementedError
python
I'm trying to modify a third-party dict class to make it immutable after a certain point.
With most classes, I can assign to method slots to modify behavior.
However, this doesn't seem possible with all methods in all classes. In particular for dict, I can reassign update, but not __setitem__.
Why? How are they different?
For example:
class Freezable(object):
def _not_modifiable(self, *args, **kw):
raise NotImplementedError()
def freeze(self):
"""
Disallow mutating methods from now on.
"""
print "FREEZE"
self.__setitem__ = self._not_modifiable
self.update = self._not_modifiable
# ... others
return self
class MyDict(dict, Freezable):
pass
d = MyDict()
d.freeze()
print d.__setitem__ # <bound method MyDict._not_modifiable of >
d[2] = 3 # no error -- this is incorrect.
d.update(4:5) # raise NotImplementedError
python
python
asked Mar 26 at 1:08
user48956user48956
5,19512 gold badges51 silver badges87 bronze badges
5,19512 gold badges51 silver badges87 bronze badges
1
__setitem__is a "special" method and is looked up using the class ofself, not in the instance's__dict__.
– martineau
Mar 26 at 1:14
Why isn’t update the same?
– user48956
Mar 26 at 1:15
updatedoesn't begin and end with double underscores (aka "dunder"), so no, it's not "special". Here's something about them in the documentation — notice there's noupdate— also see "special method" in the glossary.
– martineau
Mar 26 at 1:18
You may be interested in this stackoverflow.com/questions/47915937/…
– Jacques Gaudin
Mar 26 at 1:30
add a comment |
1
__setitem__is a "special" method and is looked up using the class ofself, not in the instance's__dict__.
– martineau
Mar 26 at 1:14
Why isn’t update the same?
– user48956
Mar 26 at 1:15
updatedoesn't begin and end with double underscores (aka "dunder"), so no, it's not "special". Here's something about them in the documentation — notice there's noupdate— also see "special method" in the glossary.
– martineau
Mar 26 at 1:18
You may be interested in this stackoverflow.com/questions/47915937/…
– Jacques Gaudin
Mar 26 at 1:30
1
1
__setitem__ is a "special" method and is looked up using the class of self, not in the instance's __dict__.– martineau
Mar 26 at 1:14
__setitem__ is a "special" method and is looked up using the class of self, not in the instance's __dict__.– martineau
Mar 26 at 1:14
Why isn’t update the same?
– user48956
Mar 26 at 1:15
Why isn’t update the same?
– user48956
Mar 26 at 1:15
update doesn't begin and end with double underscores (aka "dunder"), so no, it's not "special". Here's something about them in the documentation — notice there's no update — also see "special method" in the glossary.– martineau
Mar 26 at 1:18
update doesn't begin and end with double underscores (aka "dunder"), so no, it's not "special". Here's something about them in the documentation — notice there's no update — also see "special method" in the glossary.– martineau
Mar 26 at 1:18
You may be interested in this stackoverflow.com/questions/47915937/…
– Jacques Gaudin
Mar 26 at 1:30
You may be interested in this stackoverflow.com/questions/47915937/…
– Jacques Gaudin
Mar 26 at 1:30
add a comment |
1 Answer
1
active
oldest
votes
Note that you can define the class __setitem__, e.g.:
def __setitem__(self, key, value):
if self.update is Freezable._not_modifiable:
raise TypeError(' has been frozen'.format(id(self)))
dict.__setitem__(self, key, value)
(This method is a bit clumsy; there are other options. But it's one way to make it work even though Python calls the class's __setitem__ directly.)
Thank you -- seems like a good solution. I was hoping to replace the method because the original has a particularly efficient machine code implementation -- gains that are lost with wrapping the method. If there's another solution, I'd prefer that.
– user48956
Mar 26 at 20:08
Consider:def __setitem__(self, key, value): self.setitem(self, key, value)which means you can thendef setitemin the usual way and use your existing trick, just as you do forupdate.
– torek
Mar 26 at 20:18
I think that still leavesx[..] = ywith the original behavior.
– user48956
Mar 26 at 20:20
Try it out. Define__setitem__in the class to call some functionf. Havefprint that it's called and calldict.__setitem__as above. Then setself.f = self._not_modifiableas you do above. Then invokex[key] = y.
– torek
Mar 26 at 20:28
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55348488%2fwhy-can-i-reassign-dict-update-but-not-dict-setitem%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Note that you can define the class __setitem__, e.g.:
def __setitem__(self, key, value):
if self.update is Freezable._not_modifiable:
raise TypeError(' has been frozen'.format(id(self)))
dict.__setitem__(self, key, value)
(This method is a bit clumsy; there are other options. But it's one way to make it work even though Python calls the class's __setitem__ directly.)
Thank you -- seems like a good solution. I was hoping to replace the method because the original has a particularly efficient machine code implementation -- gains that are lost with wrapping the method. If there's another solution, I'd prefer that.
– user48956
Mar 26 at 20:08
Consider:def __setitem__(self, key, value): self.setitem(self, key, value)which means you can thendef setitemin the usual way and use your existing trick, just as you do forupdate.
– torek
Mar 26 at 20:18
I think that still leavesx[..] = ywith the original behavior.
– user48956
Mar 26 at 20:20
Try it out. Define__setitem__in the class to call some functionf. Havefprint that it's called and calldict.__setitem__as above. Then setself.f = self._not_modifiableas you do above. Then invokex[key] = y.
– torek
Mar 26 at 20:28
add a comment |
Note that you can define the class __setitem__, e.g.:
def __setitem__(self, key, value):
if self.update is Freezable._not_modifiable:
raise TypeError(' has been frozen'.format(id(self)))
dict.__setitem__(self, key, value)
(This method is a bit clumsy; there are other options. But it's one way to make it work even though Python calls the class's __setitem__ directly.)
Thank you -- seems like a good solution. I was hoping to replace the method because the original has a particularly efficient machine code implementation -- gains that are lost with wrapping the method. If there's another solution, I'd prefer that.
– user48956
Mar 26 at 20:08
Consider:def __setitem__(self, key, value): self.setitem(self, key, value)which means you can thendef setitemin the usual way and use your existing trick, just as you do forupdate.
– torek
Mar 26 at 20:18
I think that still leavesx[..] = ywith the original behavior.
– user48956
Mar 26 at 20:20
Try it out. Define__setitem__in the class to call some functionf. Havefprint that it's called and calldict.__setitem__as above. Then setself.f = self._not_modifiableas you do above. Then invokex[key] = y.
– torek
Mar 26 at 20:28
add a comment |
Note that you can define the class __setitem__, e.g.:
def __setitem__(self, key, value):
if self.update is Freezable._not_modifiable:
raise TypeError(' has been frozen'.format(id(self)))
dict.__setitem__(self, key, value)
(This method is a bit clumsy; there are other options. But it's one way to make it work even though Python calls the class's __setitem__ directly.)
Note that you can define the class __setitem__, e.g.:
def __setitem__(self, key, value):
if self.update is Freezable._not_modifiable:
raise TypeError(' has been frozen'.format(id(self)))
dict.__setitem__(self, key, value)
(This method is a bit clumsy; there are other options. But it's one way to make it work even though Python calls the class's __setitem__ directly.)
answered Mar 26 at 1:35
torektorek
214k21 gold badges276 silver badges361 bronze badges
214k21 gold badges276 silver badges361 bronze badges
Thank you -- seems like a good solution. I was hoping to replace the method because the original has a particularly efficient machine code implementation -- gains that are lost with wrapping the method. If there's another solution, I'd prefer that.
– user48956
Mar 26 at 20:08
Consider:def __setitem__(self, key, value): self.setitem(self, key, value)which means you can thendef setitemin the usual way and use your existing trick, just as you do forupdate.
– torek
Mar 26 at 20:18
I think that still leavesx[..] = ywith the original behavior.
– user48956
Mar 26 at 20:20
Try it out. Define__setitem__in the class to call some functionf. Havefprint that it's called and calldict.__setitem__as above. Then setself.f = self._not_modifiableas you do above. Then invokex[key] = y.
– torek
Mar 26 at 20:28
add a comment |
Thank you -- seems like a good solution. I was hoping to replace the method because the original has a particularly efficient machine code implementation -- gains that are lost with wrapping the method. If there's another solution, I'd prefer that.
– user48956
Mar 26 at 20:08
Consider:def __setitem__(self, key, value): self.setitem(self, key, value)which means you can thendef setitemin the usual way and use your existing trick, just as you do forupdate.
– torek
Mar 26 at 20:18
I think that still leavesx[..] = ywith the original behavior.
– user48956
Mar 26 at 20:20
Try it out. Define__setitem__in the class to call some functionf. Havefprint that it's called and calldict.__setitem__as above. Then setself.f = self._not_modifiableas you do above. Then invokex[key] = y.
– torek
Mar 26 at 20:28
Thank you -- seems like a good solution. I was hoping to replace the method because the original has a particularly efficient machine code implementation -- gains that are lost with wrapping the method. If there's another solution, I'd prefer that.
– user48956
Mar 26 at 20:08
Thank you -- seems like a good solution. I was hoping to replace the method because the original has a particularly efficient machine code implementation -- gains that are lost with wrapping the method. If there's another solution, I'd prefer that.
– user48956
Mar 26 at 20:08
Consider:
def __setitem__(self, key, value): self.setitem(self, key, value) which means you can then def setitem in the usual way and use your existing trick, just as you do for update.– torek
Mar 26 at 20:18
Consider:
def __setitem__(self, key, value): self.setitem(self, key, value) which means you can then def setitem in the usual way and use your existing trick, just as you do for update.– torek
Mar 26 at 20:18
I think that still leaves
x[..] = y with the original behavior.– user48956
Mar 26 at 20:20
I think that still leaves
x[..] = y with the original behavior.– user48956
Mar 26 at 20:20
Try it out. Define
__setitem__ in the class to call some function f. Have f print that it's called and call dict.__setitem__ as above. Then set self.f = self._not_modifiable as you do above. Then invoke x[key] = y.– torek
Mar 26 at 20:28
Try it out. Define
__setitem__ in the class to call some function f. Have f print that it's called and call dict.__setitem__ as above. Then set self.f = self._not_modifiable as you do above. Then invoke x[key] = y.– torek
Mar 26 at 20:28
add a comment |
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55348488%2fwhy-can-i-reassign-dict-update-but-not-dict-setitem%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
__setitem__is a "special" method and is looked up using the class ofself, not in the instance's__dict__.– martineau
Mar 26 at 1:14
Why isn’t update the same?
– user48956
Mar 26 at 1:15
updatedoesn't begin and end with double underscores (aka "dunder"), so no, it's not "special". Here's something about them in the documentation — notice there's noupdate— also see "special method" in the glossary.– martineau
Mar 26 at 1:18
You may be interested in this stackoverflow.com/questions/47915937/…
– Jacques Gaudin
Mar 26 at 1:30