Question about classes

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Ben

    #1

    Question about classes

    Consider:

    class foo:
    x = 5

    def getx(r):
    a = foo()
    if r != 0:
    a.x = r
    return a

    a = getx(8)

    ------------------------------------------------
    the above works (unless I typoed it, I'm tired)

    this illustrates instatiation of a class with initialization dependent
    upon a passed parameter. Seems quite useful in the general sense (in fact,
    I have a use for it, which is what led me to this.) But this doesn't work:

    class foo(xstart):
    x = 5
    if xstart != 0:
    x = xstart

    a = foo(8)

    What I am curious about is why not? What am I missing about classes here?
    Is the functionality delivered in some other fashion, or must I:

    class foo:
    x = 5

    a = foo()
    a.x = 8

    to get the brevity and clarity of...

    class foo(xstart):
    x = 5
    if xstart != 0:
    x = xstart

    a = foo(8)

    Thanks for any input on this.

  • Steven Bethard

    #2
    Re: Question about classes

    Ben wrote:[color=blue]
    > class foo(xstart):
    > x = 5
    > if xstart != 0:
    > x = xstart
    >
    > a = foo(8)
    >
    > What I am curious about is why not? What am I missing about classes here?
    > Is the functionality delivered in some other fashion, or must I:
    >
    > class foo:
    > x = 5
    >
    > a = foo()
    > a.x = 8[/color]

    The parentheses after a class name do not indicate a parameter list;
    they indicate the list of base classes. So generally, they must by
    classes/types:
    [color=blue][color=green][color=darkred]
    >>> def make_class(base ):[/color][/color][/color]
    .... class C(base):
    .... pass
    .... return C
    ....[color=blue][color=green][color=darkred]
    >>> make_class(obje ct)[/color][/color][/color]
    <class '__main__.C'>[color=blue][color=green][color=darkred]
    >>> make_class(1)[/color][/color][/color]
    Traceback (most recent call last):
    File "<interacti ve input>", line 1, in ?
    File "<interacti ve input>", line 2, in make_class
    TypeError: Error when calling the metaclass bases
    int() takes at most 2 arguments (3 given)

    If you want to set a class or instance variable for an object at
    instantiation time, you probably want to supply the __init__ method:
    [color=blue][color=green][color=darkred]
    >>> class C(object):[/color][/color][/color]
    .... x = 5
    .... def __init__(self, x):
    .... if x != 0:
    .... C.x = x
    ....[color=blue][color=green][color=darkred]
    >>> c = C(0)
    >>> c.x[/color][/color][/color]
    5[color=blue][color=green][color=darkred]
    >>> c = C(8)
    >>> c.x[/color][/color][/color]
    8

    It seems strange to me that you want to set a *class* variable here, not
    an instance variable, though perhaps you have your reasons. Note that
    by doing so, every time you make a new instance, you'll change the x
    attribute for all objects:
    [color=blue][color=green][color=darkred]
    >>> C.x[/color][/color][/color]
    5[color=blue][color=green][color=darkred]
    >>> c1 = C(0)
    >>> c1.x[/color][/color][/color]
    5[color=blue][color=green][color=darkred]
    >>> C.x[/color][/color][/color]
    5[color=blue][color=green][color=darkred]
    >>> c2 = C(8)
    >>> c2.x[/color][/color][/color]
    8[color=blue][color=green][color=darkred]
    >>> c1.x[/color][/color][/color]
    8[color=blue][color=green][color=darkred]
    >>> C.x[/color][/color][/color]
    8

    If instead, you intended to set an instance variable, you might write it
    like:
    [color=blue][color=green][color=darkred]
    >>> class C(object):[/color][/color][/color]
    .... def __init__(self, x):
    .... if x != 0:
    .... self.x = x
    .... else:
    .... self.x = 5
    ....[color=blue][color=green][color=darkred]
    >>> c = C(0)
    >>> c.x[/color][/color][/color]
    5[color=blue][color=green][color=darkred]
    >>> c = C(8)
    >>> c.x[/color][/color][/color]
    8

    Steve

    Comment

    • Steve Holden

      #3
      Re: Question about classes

      Steven Bethard wrote:
      [color=blue]
      > Ben wrote:
      >[color=green]
      >> class foo(xstart):
      >> x = 5
      >> if xstart != 0:
      >> x = xstart
      >>
      >> a = foo(8)
      >>
      >> What I am curious about is why not? What am I missing about classes here?
      >> Is the functionality delivered in some other fashion, or must I:
      >>
      >> class foo:
      >> x = 5
      >>
      >> a = foo()
      >> a.x = 8[/color]
      >
      >
      > The parentheses after a class name do not indicate a parameter list;
      > they indicate the list of base classes. So generally, they must by
      > classes/types:
      >[color=green][color=darkred]
      > >>> def make_class(base ):[/color][/color]
      > .... class C(base):
      > .... pass
      > .... return C
      > ....[color=green][color=darkred]
      > >>> make_class(obje ct)[/color][/color]
      > <class '__main__.C'>[color=green][color=darkred]
      > >>> make_class(1)[/color][/color]
      > Traceback (most recent call last):
      > File "<interacti ve input>", line 1, in ?
      > File "<interacti ve input>", line 2, in make_class
      > TypeError: Error when calling the metaclass bases
      > int() takes at most 2 arguments (3 given)
      >
      > If you want to set a class or instance variable for an object at
      > instantiation time, you probably want to supply the __init__ method:
      >[color=green][color=darkred]
      > >>> class C(object):[/color][/color]
      > .... x = 5
      > .... def __init__(self, x):
      > .... if x != 0:
      > .... C.x = x
      > ....[color=green][color=darkred]
      > >>> c = C(0)
      > >>> c.x[/color][/color]
      > 5[color=green][color=darkred]
      > >>> c = C(8)
      > >>> c.x[/color][/color]
      > 8
      >
      > It seems strange to me that you want to set a *class* variable here, not
      > an instance variable, though perhaps you have your reasons. Note that
      > by doing so, every time you make a new instance, you'll change the x
      > attribute for all objects:
      >[color=green][color=darkred]
      > >>> C.x[/color][/color]
      > 5[color=green][color=darkred]
      > >>> c1 = C(0)
      > >>> c1.x[/color][/color]
      > 5[color=green][color=darkred]
      > >>> C.x[/color][/color]
      > 5[color=green][color=darkred]
      > >>> c2 = C(8)
      > >>> c2.x[/color][/color]
      > 8[color=green][color=darkred]
      > >>> c1.x[/color][/color]
      > 8[color=green][color=darkred]
      > >>> C.x[/color][/color]
      > 8
      >
      > If instead, you intended to set an instance variable, you might write it
      > like:
      >[color=green][color=darkred]
      > >>> class C(object):[/color][/color]
      > .... def __init__(self, x):
      > .... if x != 0:
      > .... self.x = x
      > .... else:
      > .... self.x = 5
      > ....[color=green][color=darkred]
      > >>> c = C(0)
      > >>> c.x[/color][/color]
      > 5[color=green][color=darkred]
      > >>> c = C(8)
      > >>> c.x[/color][/color]
      > 8
      >
      > Steve[/color]

      Don't forget, though, that due to the attribute resolution order, if an
      instance doesn't have a particular attribute but the class does then a
      reference to the attribute in a method will get the class attribute.

      This has been used to implement class defaults in the past.

      regards
      another Steve
      --


      Holden Web LLC +1 800 494 3119

      Comment

      • Ben

        #4
        Re: Question about classes

        On Mon, 22 Nov 2004 06:39:53 +0000, Steven Bethard wrote:
        [color=blue]
        > If instead, you intended to set an instance variable, you might write it
        > like:
        >[color=green][color=darkred]
        > >>> class C(object):[/color][/color]
        > ... def __init__(self, x):
        > ... if x != 0:
        > ... self.x = x
        > ... else:
        > ... self.x = 5
        > ...[color=green][color=darkred]
        > >>> c = C(0)
        > >>> c.x[/color][/color]
        > 5[color=green][color=darkred]
        > >>> c = C(8)
        > >>> c.x[/color][/color]
        > 8[/color]

        Steve,

        That's exactly what I wanted. Thank you very much. I'll keep the class one
        in mind too.

        --Ben


        --Ben

        Comment

        • Steven Bethard

          #5
          Re: Question about classes

          Ben wrote:[color=blue]
          > On Mon, 22 Nov 2004 06:39:53 +0000, Steven Bethard wrote:
          >[color=green][color=darkred]
          >> >>> class C(object):[/color]
          >>... def __init__(self, x):
          >>... if x != 0:
          >>... self.x = x
          >>... else:
          >>... self.x = 5
          >>...[color=darkred]
          >> >>> c = C(0)
          >> >>> c.x[/color]
          >>5[color=darkred]
          >> >>> c = C(8)
          >> >>> c.x[/color]
          >>8[/color]
          >
          >
          > Steve,
          >
          > That's exactly what I wanted. Thank you very much. I'll keep the class one
          > in mind too.[/color]

          You're welcome. Depending on your goal here, you might also find that
          default argument values are helpful:
          [color=blue][color=green][color=darkred]
          >>> class C(object):[/color][/color][/color]
          .... def __init__(self, x=5):
          .... self.x = x
          ....[color=blue][color=green][color=darkred]
          >>> c = C()
          >>> c.x[/color][/color][/color]
          5[color=blue][color=green][color=darkred]
          >>> c = C(8)
          >>> c.x[/color][/color][/color]
          8[color=blue][color=green][color=darkred]
          >>> c = C(0)
          >>> c.x[/color][/color][/color]
          0

          Steve

          Comment

          Working...