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;








1















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









share|improve this question

















  • 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












  • 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












  • You may be interested in this stackoverflow.com/questions/47915937/…

    – Jacques Gaudin
    Mar 26 at 1:30

















1















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









share|improve this question

















  • 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












  • 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












  • You may be interested in this stackoverflow.com/questions/47915937/…

    – Jacques Gaudin
    Mar 26 at 1:30













1












1








1








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









share|improve this question














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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










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 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












  • 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












  • 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












  • 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












  • 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












1 Answer
1






active

oldest

votes


















2














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.)






share|improve this answer























  • 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












  • 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










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
);



);













draft saved

draft discarded


















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









2














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.)






share|improve this answer























  • 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












  • 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















2














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.)






share|improve this answer























  • 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












  • 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













2












2








2







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.)






share|improve this answer













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.)







share|improve this answer












share|improve this answer



share|improve this answer










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 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











  • 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

















  • 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












  • 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
















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








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.



















draft saved

draft discarded
















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

SQL error code 1064 with creating Laravel foreign keysForeign key constraints: When to use ON UPDATE and ON DELETEDropping column with foreign key Laravel error: General error: 1025 Error on renameLaravel SQL Can't create tableLaravel Migration foreign key errorLaravel php artisan migrate:refresh giving a syntax errorSQLSTATE[42S01]: Base table or view already exists or Base table or view already exists: 1050 Tableerror in migrating laravel file to xampp serverSyntax error or access violation: 1064:syntax to use near 'unsigned not null, modelName varchar(191) not null, title varchar(191) not nLaravel cannot create new table field in mysqlLaravel 5.7:Last migration creates table but is not registered in the migration table

용인 삼성생명 블루밍스 목차 통계 역대 감독 선수단 응원단 경기장 같이 보기 외부 링크 둘러보기 메뉴samsungblueminx.comeh선수 명단용인 삼성생명 블루밍스용인 삼성생명 블루밍스ehsamsungblueminx.comeheheheh

155 수학 과학 기타 둘러보기 메뉴eh추가해eh문서를 완성해