Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #8972 > unrolled thread

Re: Does hashlib support a file mode?

Started byPhlip <phlip2005@gmail.com>
First post2011-07-06 12:07 -0700
Last post2011-07-06 13:24 -0700
Articles 8 — 8 participants

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: Does hashlib support a file mode? Phlip <phlip2005@gmail.com> - 2011-07-06 12:07 -0700
    Re: Does hashlib support a file mode? geremy condra <debatem1@gmail.com> - 2011-07-06 15:15 -0400
    Re: Does hashlib support a file mode? Andrew Berg <bahamutzero8825@gmail.com> - 2011-07-06 14:42 -0500
    Re: Does hashlib support a file mode? Mel <mwilson@the-wire.com> - 2011-07-06 15:43 -0400
      Re: Does hashlib support a file mode? Anssi Saari <as@sci.fi> - 2011-07-07 14:29 +0300
        Re: Does hashlib support a file mode? Paul Rudin <paul.nospam@rudin.co.uk> - 2011-07-07 13:13 +0100
    Re: Does hashlib support a file mode? Ian Kelly <ian.g.kelly@gmail.com> - 2011-07-06 13:48 -0600
    Re: Does hashlib support a file mode? Ethan Furman <ethan@stoneleaf.us> - 2011-07-06 13:24 -0700

#8972 — Re: Does hashlib support a file mode?

FromPhlip <phlip2005@gmail.com>
Date2011-07-06 12:07 -0700
SubjectRe: Does hashlib support a file mode?
Message-ID<5a4867f1-929c-4cde-b47e-4b11de767f39@h38g2000pro.googlegroups.com>
On Jul 6, 11:42 am, Andrew Berg <bahamutzero8...@gmail.com> wrote:
> On 2011.07.06 12:38 PM, Phlip wrote:> Python sucks. m = md5() looks like an initial assignment, not a
> > special magic storage mode. Principle of least surprise fail, and
> > principle of most helpful default behavior fail.
>
> func() = whatever the function returns
> func = the function object itself (in Python, everything's an object)
>
> Maybe you have Python confused with another language (I don't know what
> exactly you mean by initial assignment). Typically one does not need
> more than one name for a function/method. When a function/method is
> defined, it gets created as a function object and occupies the namespace
> in which it's defined.

If I call m = md5() twice, I expect two objects.

I am now aware that Python bends the definition of "call" based on
where the line occurs. Principle of least surprise.

[toc] | [next] | [standalone]


#8973

Fromgeremy condra <debatem1@gmail.com>
Date2011-07-06 15:15 -0400
Message-ID<mailman.716.1309979758.1164.python-list@python.org>
In reply to#8972
On Wed, Jul 6, 2011 at 3:07 PM, Phlip <phlip2005@gmail.com> wrote:
> On Jul 6, 11:42 am, Andrew Berg <bahamutzero8...@gmail.com> wrote:
>> On 2011.07.06 12:38 PM, Phlip wrote:> Python sucks. m = md5() looks like an initial assignment, not a
>> > special magic storage mode. Principle of least surprise fail, and
>> > principle of most helpful default behavior fail.
>>
>> func() = whatever the function returns
>> func = the function object itself (in Python, everything's an object)
>>
>> Maybe you have Python confused with another language (I don't know what
>> exactly you mean by initial assignment). Typically one does not need
>> more than one name for a function/method. When a function/method is
>> defined, it gets created as a function object and occupies the namespace
>> in which it's defined.
>
> If I call m = md5() twice, I expect two objects.
>
> I am now aware that Python bends the definition of "call" based on
> where the line occurs. Principle of least surprise.

Python doesn't do anything to the definition of call. If you call
hashlib.md5() twice, you get two objects:

>>> import hashlib
>>> m1 = hashlib.md5()
>>> m2 = hashlib.md5()
>>> id(m1)
139724897544712
>>> id(m2)
139724897544880

Geremy Condra

[toc] | [prev] | [next] | [standalone]


#8978

FromAndrew Berg <bahamutzero8825@gmail.com>
Date2011-07-06 14:42 -0500
Message-ID<mailman.719.1309981365.1164.python-list@python.org>
In reply to#8972
On 2011.07.06 02:07 PM, Phlip wrote:
> If I call m = md5() twice, I expect two objects.
You get two objects because you make the function run again. Of course,
the first one is garbage collected if it doesn't have another reference.

>>> m1 = hashlib.md5()
>>> m2 = hashlib.md5()
>>> m1 is m2
False

Are you assuming Python acts like another language or is there something
confusing in the docs or something else?

[toc] | [prev] | [next] | [standalone]


#8979

FromMel <mwilson@the-wire.com>
Date2011-07-06 15:43 -0400
Message-ID<iv2dte$mp6$1@speranza.aioe.org>
In reply to#8972
Phlip wrote:

> If I call m = md5() twice, I expect two objects.
> 
> I am now aware that Python bends the definition of "call" based on
> where the line occurs. Principle of least surprise.

Actually, in

def file_to_hash(path, m = hashlib.md5()):

hashlib.md5 *is* called once; that is when the def statement is executed.

Later on, when file_to_hash gets called, the value of m is either used as 
is, as the default parameter, or is replaced for the duration of the call by 
another object supplied by the caller.

	Mel.

	

[toc] | [prev] | [next] | [standalone]


#9020

FromAnssi Saari <as@sci.fi>
Date2011-07-07 14:29 +0300
Message-ID<vg3k4buib19.fsf@pepper.modeemi.fi>
In reply to#8979
Mel <mwilson@the-wire.com> writes:

> def file_to_hash(path, m = hashlib.md5()):
>
> hashlib.md5 *is* called once; that is when the def statement is executed.

Very interesting, I certainly wasn't clear on this. So after that def,
the created hashlib object is in the module's scope and can be
accessed via file_to_hash.__defaults__[0].

[toc] | [prev] | [next] | [standalone]


#9022

FromPaul Rudin <paul.nospam@rudin.co.uk>
Date2011-07-07 13:13 +0100
Message-ID<87aacq70gt.fsf@no-fixed-abode.cable.virginmedia.net>
In reply to#9020
Anssi Saari <as@sci.fi> writes:

> Mel <mwilson@the-wire.com> writes:
>
>> def file_to_hash(path, m = hashlib.md5()):
>>
>> hashlib.md5 *is* called once; that is when the def statement is executed.
>
> Very interesting, I certainly wasn't clear on this. So after that def,
> the created hashlib object is in the module's scope and can be
> accessed via file_to_hash.__defaults__[0].

This also why you have to be a bit careful if you use e.g. [] or {} as a
default argument - if you then modify these things within the function
you might not end up with what you expect - it's the same list or
dictionary each time the function is called.  So to avoid that kind of
thing you end up with code like:

def foo(bar=None):
   if bar is None:
       bar = []
   ...

[toc] | [prev] | [next] | [standalone]


#8980

FromIan Kelly <ian.g.kelly@gmail.com>
Date2011-07-06 13:48 -0600
Message-ID<mailman.720.1309981747.1164.python-list@python.org>
In reply to#8972
On Wed, Jul 6, 2011 at 1:07 PM, Phlip <phlip2005@gmail.com> wrote:
> If I call m = md5() twice, I expect two objects.
>
> I am now aware that Python bends the definition of "call" based on
> where the line occurs. Principle of least surprise.

There is no definition-bending.  The code:

"""
def file_to_hash(path, m = hashlib.md5()):
    # do stuff...

file_to_hash(path1)
file_to_hash(path2)
"""

does not call hashlib.md5 twice.  It calls it *once*, at the time the
file_to_hash function is defined.  The returned object is stored on
the function object, and that same object is passed into file_to_hash
as a default value each time the function is called.  See:

http://docs.python.org/reference/compound_stmts.html#function

[toc] | [prev] | [next] | [standalone]


#8983

FromEthan Furman <ethan@stoneleaf.us>
Date2011-07-06 13:24 -0700
Message-ID<mailman.723.1309983006.1164.python-list@python.org>
In reply to#8972
Phlip wrote:
>> On 2011.07.06 12:38 PM, Phlip wrote:
>>> Python sucks. m = md5() looks like an initial assignment, not a
>>> special magic storage mode. Principle of least surprise fail, and
>>> principle of most helpful default behavior fail.
 >>>
> 
> If I call m = md5() twice, I expect two objects.

You didn't call md5 twice -- you called it once when you defined the 
function.

Phlips naive code:
---
def file_to_hash(path, m = hashlib.md5()):
                        \---------------/
                         happens once, when
                         def line is executed


If you want separate md5 objects, don't create just one when you create 
the function, create one inside the function:

def file_to_hash(path, m = None):
     if m is None:
         m = hashlib.md5()


You should try the Principle of Learning the Language.

~Ethan~

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web