Problems with properties

M

Michael Schneider

Hello All,

I have been working on learning how to use python properties.

The get property access is working, but the the set
property is not working.

Rather then dispatching the property assignment to setNothing, the
property object is being replaced with a string.

I must be doing something very stupid here.

Could someone please point out my error, I have dents in my forehead
for this one.

Thanks,
Mike



------------------------------------------------------------------

from unittest import TestCase
import unittest


class Task:
def __init__(self,command):
self._command = command

def setNothing(self, value):
raise AttributeError

def getCommand(self):
return self._command

command=property(getCommand, setNothing)


class taskTest(TestCase):

def testTask(self):
t = Task("dir c:")
c = t.command
self.assertEquals("dir c:", c)

# should fail, but doesn't
t.command = "foo Bar"

self.assertEquals("dir c:", t.command)



if __name__ == "__main__":
unittest.main()
 
W

wittempj

If you change it to this it works. You should provide a get and a set
function for a property.

class Task:
def __init__(self, value):
self._command = value

def setCommand(self, value):
self._command = value


def getCommand(self):
return self._command

command=property(getCommand, setCommand)

class taskTest(TestCase):
def testTask(self):
t = Task("dir c:")
c = t.command
self.assertEquals("dir c:", c)

# should fail, but doesn't
t.command = "foo Bar"
self.assertEquals("dir c:", t.command)


if __name__ == "__main__":
unittest.main()
 
W

wittempj

If you change it to this it works. You should provide a get and a set
function for a property.

class Task:
def __init__(self, value):
self._command = value

def setCommand(self, value):
self._command = value


def getCommand(self):
return self._command

command=property(getCommand, setCommand)

class taskTest(TestCase):
def testTask(self):
t = Task("dir c:")
c = t.command
self.assertEquals("dir c:", c)

# should fail, but doesn't
t.command = "foo Bar"
self.assertEquals("dir c:", t.command)


if __name__ == "__main__":
unittest.main()
 
B

Benji York

Michael said:
The get property access is working, but the the set
property is not working.

The classes need to be "new style" for properties to work right. Just
change "class Task:" to "class Task(object):".

Your "setNothing" method is unnecessary, if you don't proved a "setter"
an exception will be raised automatically. Also (if you're using Python
2.4) you probably want to look at decorator syntax.

So you're class could look like this:

class Task(object):
def __init__(self,command):
self._command = command

@property
def command(self):
return self._command
 
P

Peter Otten

Michael said:
Rather then dispatching the property assignment to setNothing, the
property object is being replaced with a string.

properties are for newstyle classes only (i. e. classes that inherit from
object).

from unittest import TestCase
import unittest

class Task(object):
def __init__(self,command):
self._command = command

def setNothing(self, value):
raise AttributeError

def getCommand(self):
return self._command

command=property(getCommand, setNothing)
# or just
# command=property(getCommand)


class taskTest(TestCase):

def testTask(self):
t = Task("dir c:")
c = t.command
self.assertEquals("dir c:", c)

def set():
t.command = "foo Bar"
self.assertRaises(AttributeError, set)

self.assertEquals("dir c:", t.command)



if __name__ == "__main__":
unittest.main()

Peter
 
S

shawn

I was thinking that in Python2.4, all class definitions inherited from
new-style classes. There may be a bug here. I can make your code work
as expected by changing the class definition to:

class Task(object):


with that change, the assignment raises an attribute error. You could
also accomplish the same thing by eliminating the setNothing method and
defining your property as:

command=property(getCommand)

or for a really simple case like this, you could even leave off the
getCommand function and define the property as:

command=property(lambda self: self._command)

(although I am sure personal tastes vary as to style here).
 
G

Gerrit Holl

Michael said:
Could someone please point out my error, I have dents in my forehead
for this one.

Here you need to add:

__metaclass__ = type

this will make your classes new-style.

Gerrit.
 
M

Michael Schneider

Thanks to all, I added the object as a subclass (should this be
required for 2.4.1 ???)

I also switched to the decorator with the @property syntax

Thank you very much for the help for adding @property to the language.

what a great language :)

Mike
 
M

Michael Schneider

Thanks to all, I added the object as a subclass (should this be
required for 2.4.1 ???)

I also switched to the decorator with the @property syntax

Thank you very much for the help for adding @property to the language.

what a great language :)

Mike
 
A

Alex Martelli

Michael Schneider said:
Thanks to all, I added the object as a subclass (should this be
required for 2.4.1 ???)

It _IS_ required, because Python these days moves *very slowly indeed*
before changing semantics of existing code in any way that is not
backwards compatible -- we just don't want to break good working code,
and there are many millions of lines' worth of such Python code in use
around the world. The newstyle object model cannot have identical
semantics to the legacy (AKA "classic") one, so it can't become the
default without LOTS AND LOTS of years spent with the old-style mode
being discouraged and deprecated... but STILL the default.

As usual, "should" is a harder question to answer -- one might
reasonably say that maintainers of legacy code have had PLENTY of
warning time by now, and newstyle OM "should" become the default by,
say, 2.6, rather than waiting for 3.0. But, that's not an easy issue to
call!


Alex
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,268
Messages
2,571,344
Members
48,019
Latest member
Migration_Expert

Latest Threads

Top