Best way to control assignment to attribute?

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

    Best way to control assignment to attribute?

    Hi all

    I want to control the assignment of a value to an attribute. Instead
    of allowing it to be changed directly, I want to enforce that a method
    is called, which will perform the assignment subject to various
    checks.

    From reading the manuals, this is one way to do it.

    class frank:
    def __init__(self,x ):
    self.setval_x(x )

    def __setattr__(sel f,name,value):
    if name == 'x':
    raise 'cannot change value of x - use setval_x(value) '
    else:
    self.__dict__[name] = value

    def setval_x(self,v alue):
    ok = 1
    # perform any checks required
    if ok:
    self.__dict__['x'] = value

    Is this the best way, or does anyone have any other suggestions?

    I notice that an application can beat this by using the __dict__
    syntax itself. Is there any way to prevent this? Just curious, it is
    not a major concern.

    Any comments will be appreciated.

    Thanks

    Frank Millman
  • Peter Otten

    #2
    Re: Best way to control assignment to attribute?

    Frank Millman wrote:
    [color=blue]
    > Hi all
    >
    > I want to control the assignment of a value to an attribute. Instead
    > of allowing it to be changed directly, I want to enforce that a method
    > is called, which will perform the assignment subject to various
    > checks.
    >
    > From reading the manuals, this is one way to do it.
    >
    > class frank:
    > def __init__(self,x ):
    > self.setval_x(x )
    >
    > def __setattr__(sel f,name,value):
    > if name == 'x':
    > raise 'cannot change value of x - use setval_x(value) '[/color]

    I think you shouldn't use string exceptions in new code anymore.
    [color=blue]
    > else:
    > self.__dict__[name] = value
    >
    > def setval_x(self,v alue):
    > ok = 1
    > # perform any checks required
    > if ok:
    > self.__dict__['x'] = value
    >
    > Is this the best way, or does anyone have any other suggestions?
    >
    > I notice that an application can beat this by using the __dict__
    > syntax itself. Is there any way to prevent this? Just curious, it is
    > not a major concern.
    >
    > Any comments will be appreciated.
    >
    > Thanks
    >
    > Frank Millman[/color]

    Use new style classes and properties:
    [color=blue][color=green][color=darkred]
    >>> class Frank(object):[/color][/color][/color]
    .... def __init__(self, x):
    .... self.x = x
    .... def getX(self):
    .... return self._x
    .... def setX(self, x):
    .... if x < 0:
    .... raise ValueError("x must be >= 0")
    .... self._x = x
    .... x = property(getX, setX)
    ....[color=blue][color=green][color=darkred]
    >>> f = Frank(3)
    >>> f.x = 2
    >>> f.x = -2[/color][/color][/color]
    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    File "<stdin>", line 8, in setX
    ValueError: x must be >= 0

    The main advantage is cleaner code, which will become more obvious as the
    number of special attributes increases. Also, checked and normal attribute
    access is transparent to the client.

    Peter

    Comment

    • Gerrit Holl

      #3
      Re: Best way to control assignment to attribute?

      Frank Millman wrote:[color=blue]
      > I want to control the assignment of a value to an attribute. Instead
      > of allowing it to be changed directly, I want to enforce that a method
      > is called, which will perform the assignment subject to various
      > checks.[/color]

      I think it is possible with new-style classes, introduced in Python 2.2.


      The official home of the Python Programming Language


      Gerrit.

      --
      PrePEP: Builtin path type

      Asperger's Syndrome - a personal approach:


      Comment

      • wes weston

        #4
        Re: Best way to control assignment to attribute?

        Frank,
        See __slots__; not sure if there's a newer/better way.

        wes



        Frank Millman wrote:[color=blue]
        > Hi all
        >
        > I want to control the assignment of a value to an attribute. Instead
        > of allowing it to be changed directly, I want to enforce that a method
        > is called, which will perform the assignment subject to various
        > checks.
        >
        > From reading the manuals, this is one way to do it.
        >
        > class frank:
        > def __init__(self,x ):
        > self.setval_x(x )
        >
        > def __setattr__(sel f,name,value):
        > if name == 'x':
        > raise 'cannot change value of x - use setval_x(value) '
        > else:
        > self.__dict__[name] = value
        >
        > def setval_x(self,v alue):
        > ok = 1
        > # perform any checks required
        > if ok:
        > self.__dict__['x'] = value
        >
        > Is this the best way, or does anyone have any other suggestions?
        >
        > I notice that an application can beat this by using the __dict__
        > syntax itself. Is there any way to prevent this? Just curious, it is
        > not a major concern.
        >
        > Any comments will be appreciated.
        >
        > Thanks
        >
        > Frank Millman[/color]

        Comment

        • Aahz

          #5
          Re: Best way to control assignment to attribute?

          In article <XF9Ub.175053$6 y6.3406052@bgtn sc05-news.ops.worldn et.att.net>,
          wes weston <wweston@att.ne t> wrote:[color=blue]
          >Frank Millman wrote:[color=green]
          >>
          >> I want to control the assignment of a value to an attribute. Instead
          >> of allowing it to be changed directly, I want to enforce that a method
          >> is called, which will perform the assignment subject to various
          >> checks.[/color]
          >
          > See __slots__; not sure if there's a newer/better way.[/color]

          You should be certain before even thinking of suggesting __slots__.
          __slots__ is intended only to save memory; there are many problems with
          using it if you don't know what you're doing.
          --
          Aahz (aahz@pythoncra ft.com) <*> http://www.pythoncraft.com/

          "The joy of coding Python should be in seeing short, concise, readable
          classes that express a lot of action in a small amount of clear code --
          not in reams of trivial code that bores the reader to death." --GvR

          Comment

          • wes weston

            #6
            Re: Best way to control assignment to attribute?

            Aahz,
            He might be more interested in naming his class vars
            with two leading underscores. eh? This mangles the name
            making it not as it appears in the text and not accessible
            by the expressed name. Does not the __slots__ statement
            keep "you" from creating a new unintended class var?
            wes

            Aahz wrote:[color=blue]
            > In article <XF9Ub.175053$6 y6.3406052@bgtn sc05-news.ops.worldn et.att.net>,
            > wes weston <wweston@att.ne t> wrote:
            >[color=green]
            >>Frank Millman wrote:
            >>[color=darkred]
            >>>I want to control the assignment of a value to an attribute. Instead
            >>>of allowing it to be changed directly, I want to enforce that a method
            >>>is called, which will perform the assignment subject to various
            >>>checks.[/color]
            >>
            >> See __slots__; not sure if there's a newer/better way.[/color]
            >
            >
            > You should be certain before even thinking of suggesting __slots__.
            > __slots__ is intended only to save memory; there are many problems with
            > using it if you don't know what you're doing.[/color]

            Comment

            • Aahz

              #7
              Re: Best way to control assignment to attribute?

              Wes, please don't top-post. Consider the following:

              A: Because it messes up the order in which people normally read text.
              Q: Why is top-posting such a bad thing?
              A: Top-posting.
              Q: What is the most annoying thing on usenet?

              In article <vXbUb.55174$6O 4.1637541@bgtns c04-news.ops.worldn et.att.net>,
              wes weston <wweston@att.ne t> wrote:[color=blue]
              >Aahz wrote:[color=green]
              >> In article <XF9Ub.175053$6 y6.3406052@bgtn sc05-news.ops.worldn et.att.net>,
              >> wes weston <wweston@att.ne t> wrote:[color=darkred]
              >>>Frank Millman wrote:
              >>>>
              >>>>I want to control the assignment of a value to an attribute. Instead
              >>>>of allowing it to be changed directly, I want to enforce that a method
              >>>>is called, which will perform the assignment subject to various
              >>>>checks.
              >>>
              >>> See __slots__; not sure if there's a newer/better way.[/color]
              >>
              >> You should be certain before even thinking of suggesting __slots__.
              >> __slots__ is intended only to save memory; there are many problems with
              >> using it if you don't know what you're doing.[/color]
              >
              >He might be more interested in naming his class vars with two leading
              >underscores. eh? This mangles the name making it not as it appears
              >in the text and not accessible by the expressed name. Does not the
              >__slots__ statement keep "you" from creating a new unintended class
              >var?[/color]

              Two leading underscores would be good, but it doesn't directly solve the
              problem about controlling access to the attribute. Yes, __slots__
              prevents the creation of unintended attributes, but it also has other --
              frequently undesirable -- consequences. I encourage you to look up some
              of the old threads in Google.
              --
              Aahz (aahz@pythoncra ft.com) <*> http://www.pythoncraft.com/

              "The joy of coding Python should be in seeing short, concise, readable
              classes that express a lot of action in a small amount of clear code --
              not in reams of trivial code that bores the reader to death." --GvR

              Comment

              • Frank Millman

                #8
                Re: Best way to control assignment to attribute?

                frank@chagford. com (Frank Millman) wrote:[color=blue]
                > Hi all
                >
                > I want to control the assignment of a value to an attribute. Instead
                > of allowing it to be changed directly, I want to enforce that a method
                > is called, which will perform the assignment subject to various
                > checks.
                >[/color]

                Thanks to everybody for the replies. Clearly property() is the way to
                go.

                I have avoided new-style classes up to now, as I was waiting for a
                real need to use them. Now I have one, so it is time to roll up my
                sleeves and get stuck in.

                Thanks again.

                Frank

                Comment

                Working...