Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > default argument in method

Reply
Thread Tools

default argument in method

 
 
ernest
Guest
Posts: n/a
 
      12-12-2010
Hi,

I'd like to have a reference to an instance attribute as
default argument in a method. It doesn't work because
"self" is not defined at the time the method signature is
evaluated. For example:

class C(object):
def __init__(self):
self.foo = 5
def m(self, val=self.foo):
return val

Raises NameError because 'self' is not defined.
The obvious solution is put val=None in the signature
and set val to the appropriate value inside the method
(if val is None: ...), but I wonder if there's another way.

Cheers,
Ernest
 
Reply With Quote
 
 
 
 
Chris Rebert
Guest
Posts: n/a
 
      12-12-2010
On Sun, Dec 12, 2010 at 3:35 AM, ernest <> wrote:
> Hi,
>
> I'd like to have a reference to an instance attribute as
> default argument in a method. It doesn't work because
> "self" is not defined at the time the method signature is
> evaluated. For example:
>
> class C(object):
> Â* Â*def __init__(self):
> Â* Â* Â* Â*self.foo = 5
> Â* Â*def m(self, val=self.foo):
> Â* Â* Â* Â*return val
>
> Raises NameError because 'self' is not defined.
> The obvious solution is put val=None in the signature
> and set val to the appropriate value inside the method
> (if val is None: ...), but I wonder if there's another way.


Nope, not really. There are some more complicated slight variations on
the same theme (e.g. hoisting the idiom into a decorator), but they're
of fairly dubious merit; just use the straightforward idiom you
already outlined.

Cheers,
Chris
--
http://blog.rebertia.com
 
Reply With Quote
 
 
 
 
Jean-Michel Pichavant
Guest
Posts: n/a
 
      12-13-2010
ernest wrote:
> Hi,
>
> I'd like to have a reference to an instance attribute as
> default argument in a method. It doesn't work because
> "self" is not defined at the time the method signature is
> evaluated. For example:
>
> class C(object):
> def __init__(self):
> self.foo = 5
> def m(self, val=self.foo):
> return val
>
> Raises NameError because 'self' is not defined.
> The obvious solution is put val=None in the signature
> and set val to the appropriate value inside the method
> (if val is None: ...), but I wonder if there's another way.
>
> Cheers,
> Ernest
>

your 'val=None' is jus fine.

JM
 
Reply With Quote
 
Steve Holden
Guest
Posts: n/a
 
      12-13-2010
On 12/13/2010 12:14 PM, Godson Gera wrote:
>
>
> On Sun, Dec 12, 2010 at 5:05 PM, ernest <
> <private.php?do=newpm&u=>> wrote:
>
> Hi,
>
> I'd like to have a reference to an instance attribute as
> default argument in a method. It doesn't work because
> "self" is not defined at the time the method signature is
> evaluated. For example:
>
> class C(object):
> def __init__(self):
> self.foo = 5
> def m(self, val=self.foo):
> return val
>
> Raises NameError because 'self' is not defined.
>
>
> You can defined foo outside the __init__ and can access it inside
> methods using self.foo
>
> class C(object):
> foo=5
> def __init__(self):
> print self.foo
> def m(self,val=foo):
> return val
>
> class attributes can be accessed with out self before them in method
> signatures. However, becareful if you change the value of foo inside any
> method, the method signature will still hold on to old value.
>

You are, of course, correct. It might be more accurate to say that if
C.foo is rebound this does not change the binding of the val default
value. "Change the value of foo" could be though to include "mutate a
mutable value", but in that case both C.foo and the method's val
parameter would still be bound to the same object.

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
PyCon 2011 Atlanta March 9-17 http://us.pycon.org/
See Python Video! http://python.mirocommunity.org/
Holden Web LLC http://www.holdenweb.com/

 
Reply With Quote
 
Hans-Peter Jansen
Guest
Posts: n/a
 
      12-15-2010
On Monday 13 December 2010, 18:14:27 Godson Gera wrote:
> On Sun, Dec 12, 2010 at 5:05 PM, ernest <> wrote:
> > Hi,
> >
> > I'd like to have a reference to an instance attribute as
> > default argument in a method. It doesn't work because
> > "self" is not defined at the time the method signature is
> > evaluated. For example:
> >
> > class C(object):
> > def __init__(self):
> > self.foo = 5
> > def m(self, val=self.foo):
> > return val
> >
> > Raises NameError because 'self' is not defined.

>
> You can defined foo outside the __init__ and can access it inside
> methods using self.foo
>
> class C(object):
> foo=5
> def __init__(self):
> print self.foo
> def m(self,val=foo):
> return val
>
> class attributes can be accessed with out self before them in method
> signatures. However, becareful if you change the value of foo inside
> any method, the method signature will still hold on to old value.


Since this is a major pitfall, it might be worth mentioning, that
mutable default arguments are generally a bad idea, as the default
arguments are evaluated just once, hence e.g. using an empty list might
contain the items, that were appended in earlier calls of this method..

Code, that _relies_ on such behavior should be yanked instantaneous and
the producer of such code should be punished with coding APL¹ on a
dubeolsik hangul keyboard² for a year at least..

Pete

¹) Not, that APL is a bad language per se, but even one liners tend to
be rather cryptic for usual brains. Let's say it with Dijkstra:
"APL is a mistake, carried out through perfection..."
but given the second constraint, it's going to be a, hmm, challenge.
http://en.wikipedia.org/wiki/APL_(programming_language)
²) http://en.wikipedia.org/wiki/Keyboard_layout#Dubeolsik
 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      12-15-2010
On Wed, 15 Dec 2010 21:10:05 +0100, Hans-Peter Jansen wrote:

> Since this is a major pitfall, it might be worth mentioning, that
> mutable default arguments are generally a bad idea, as the default
> arguments are evaluated just once, hence e.g. using an empty list might
> contain the items, that were appended in earlier calls of this method..


It's only a pitfall for users who expect that default arguments are re-
created every time you call the function; it's only a bad idea for code
which relies on the default arguments being re-created each time.

If you hold misunderstandings about the behaviour of a language, you'll
have trouble understanding what code does. Default arguments are no
different from any other feature.



> Code, that _relies_ on such behavior should be yanked instantaneous and
> the producer of such code should be punished with coding APL¹ on a
> dubeolsik hangul keyboard² for a year at least..


Python code that relies on default arguments to *not* be re-created on
each function call is no worse than (say) Ruby code that relies on
default arguments *to* be re-created each time.

I don't mean to be elitist (ah, who am I fooling, of course I do), but
when coders of the skill and experience of the Effbot and Guido use
mutable defaults, who are you to say they shouldn't?

http://effbot.org/zone/default-values.htm
http://www.python.org/doc/essays/graphs/



--
Steven
 
Reply With Quote
 
Hans-Peter Jansen
Guest
Posts: n/a
 
      12-16-2010
On Thursday 16 December 2010, 00:56:31 Steven D'Aprano wrote:
> On Wed, 15 Dec 2010 21:10:05 +0100, Hans-Peter Jansen wrote:
> > Since this is a major pitfall, it might be worth mentioning, that
> > mutable default arguments are generally a bad idea, as the default
> > arguments are evaluated just once, hence e.g. using an empty list
> > might contain the items, that were appended in earlier calls of
> > this method..

>
> It's only a pitfall for users who expect that default arguments are
> re- created every time you call the function; it's only a bad idea
> for code which relies on the default arguments being re-created each
> time.
>
> If you hold misunderstandings about the behaviour of a language,
> you'll have trouble understanding what code does. Default arguments
> are no different from any other feature.
>
> > Code, that _relies_ on such behavior should be yanked instantaneous
> > and the producer of such code should be punished with coding APL¹
> > on a dubeolsik hangul keyboard² for a year at least..

>
> Python code that relies on default arguments to *not* be re-created
> on each function call is no worse than (say) Ruby code that relies on
> default arguments *to* be re-created each time.
>
> I don't mean to be elitist (ah, who am I fooling, of course I do),
> but when coders of the skill and experience of the Effbot and Guido
> use mutable defaults, who are you to say they shouldn't?
>
> http://effbot.org/zone/default-values.htm
> http://www.python.org/doc/essays/graphs/


Hmm, thanks for the pointers, Steven. I stand corrected, as I won't
argue with taste.. I like the part about the disastrous results
specially.

If such code would be used in any collaborations, I would expect an
explicit comment at least.

Pete
 
Reply With Quote
 
DevPlayer
Guest
Posts: n/a
 
      12-30-2010
There's some_object.some_method.func_defaults and
some_function.func_defaults both are a settable attribute. How to set
the methods func_defaults? You'd have to have code in
_getattribute__(yourmethod) if not __getattr__(yourmethod)

def __getattribute__(self, attr):
if attr == self.my_method:
# something like this, but i'm probably a little off
# you might need to use super or something to prevent
recursive __getattribute__ calls here
self.my_method.func_defaults = self.foo

 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      12-30-2010
On Thu, 30 Dec 2010 11:26:50 -0800, DevPlayer wrote:

> There's some_object.some_method.func_defaults


Not quite -- method objects don't expose the function attributes
directly. You need some_object.some_method.im_func to get the function
object, which then has a func_defaults attribute.


> and
> some_function.func_defaults both are a settable attribute. How to set
> the methods func_defaults?


(1) You shouldn't mess with func_defaults unless you know what you're
doing.

(2) If you do know what you are doing, you probably won't want to mess
with func_defaults.

(3) But if you insist, then you would so the same way you would set any
other object's attribute.


>>> class C(object):

.... def method(self, x=[]):
.... print x
....
>>> C().method()

[]
>>> function = inst.method.im_func
>>> function.func_defaults

([],)
>>> function.func_defaults = ("spam",)
>>> inst.method()

spam


(4) Seriously, don't do this.


> You'd have to have code in
> _getattribute__(yourmethod) if not __getattr__(yourmethod)
>
> def __getattribute__(self, attr):
> if attr == self.my_method:
> # something like this, but i'm probably a little off
> # you might need to use super or something to prevent
> recursive __getattribute__ calls here
> self.my_method.func_defaults = self.foo



*cries*

A much better solution would be:

class MyClass:
def my_method(self, x=None):
if x is None:
x = self.foo
...

Don't write slow, confusing, complex, convoluted, self-modifying code
when you can write fast, simple, straight-forward, obvious code. Unless
you're doing it to win a bet.



--
Steven
 
Reply With Quote
 
DevPlayer
Guest
Posts: n/a
 
      01-01-2011
I agree with you Steven that the OP should avoid __getattribute__ and
the like for many a thing. I also agree with your last statement. I
try to answer the OP's question without much "You shouldn't do this's
and don't do that's". I trust them to make thier own decisions. I'd
say "A much better solution..." is the way I like to say it.

The last solution you offered I find I use more often now as I like to
set my function with default values for which I call set-and-forget
function parms/args where using None is what allows my functions to
know what is changing (or not).
# for example
def logger(parm1, parm2=None):
if not hasattr(myfunc.parm2_default):
if parm2:
myfunc.parm2_default = parm2
else:
myfunc.parm2_default = CONSOLE
if not parm2:
parmTwo = myfunc.parm2_default
else:
parmTwo = parm2

# do something
print(parmTwo)

log = logger(gui_frame, GUI) # an inaccurate example
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Method default argument whose type is the class not yet defined Jennie Python 24 11-12-2012 04:46 AM
Defining a method with an argument with a default value Pedro Côrte-Real Ruby 11 07-25-2006 09:14 PM
object as a argument of the method in which the method is defined ? mike C++ 5 02-22-2006 01:24 PM
defaulting argument to previous argument Bhushit Joshipura C++ 5 12-30-2003 03:21 PM
Problem posting a method as an argument to an method.. =?ISO-8859-1?Q?Christian_M=F6rck?= C++ 4 11-21-2003 07:38 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57