views:

54

answers:

2

Using Python 2.5, I'd like to create a temporary file, but add (& modify) attributes of my own. I've tried the following:

class  TempFileWithAttributes ( ) :
    __slots__   =   [   '_tempFile' ,  'Value'  ]
    def __init__ ( self ) :
        self._tempFile  =  tempfile.TemporaryFile()
        object.__setattr__ ( self, '_tempFile', tempfile.TemporaryFile() )
        object.__setattr__ ( self, 'Value', 123 )
    def __getattr__ ( self, name ) :
        if  name  ==  'Value' :
            object.__getattr__ ( self, 'Value' )
        elif  name  ==  '_tempFile' :
            return  getattr ( self._tempFile, name )
    def __setattr__ ( self, name, newValue ) :
        if name == 'Value' :
            object.__setattr__ ( self, 'Value', newValue )
        elif  name == '_tempFile' :
            setattr ( self._tempFile, newValue )

myFile  =  TempFileWithAttributes ( )
myFile.write ( 'Hello, Jayson!' )
print myFile.Value
myFile.Value  =  456
print myFile.Value
myFile.seek ( 0, os.SEEK_END )
print myFile.tell()

However, I am greeted with the following error messages:

object.__setattr__ ( self, '_tempFile', tempfile.TemporaryFile() )
TypeError: can't apply this __setattr__ to instance object

I've also tried subclassing file, but that wasn't working, either.

Any suggestions?

A: 

First step: use setattr() instead of object.__setattr__()

Second step: Instead of setattr(anobject, 'string', value) just use anobject.string = value

Because your code makes no sense whatsoever. I can't even figure out what you are trying to do.

Lennart Regebro
This isn't an answer.
Jason Orendorff
Yes, it is. And I even tried it. Getting rid of all that nonsense `__getattr__` and `__setattr__` means it works.
Lennart Regebro
+2  A: 

Why are you overriding __setattr__ at all?! You're not doing anything useful in your override -- and your override of __getattr__ isn't being very helpful either. I think what you want is rather something like:

>>> class  TempFileWithAttributes(object):
...   __slots__ = ['_tempFile', 'Value']
...   def __init__(self):
...     self._tempFile  =  tempfile.TemporaryFile()
...     self.Value = 123
...   def __getattr__(self, name):
...     return getattr(self._tempFile, name)
... 

This does let the rest of your sample code work, presumably as intended.

Alex Martelli
Essentially the exact code I was a couple seconds away from posting. Curse you Martelli! However `__slots__` is very likely unnecessary here, so I would just drop that.
Jason Orendorff
Thank you very much, everyone, and especially you, Mr. Martelli. Your solution worked for me straightaway!
JaysonFix
@Jason, yep, `__slots__` only saves a few dozen bytes, likely irrelevant since it's unlikely that a program will have a huge number of objects of this class "alive" at the same time.
Alex Martelli
@JaysonFix, you're welcome, but do consider following Jason Orendorff's advice and just removing the `__slots__ =` line, it's not really buying you much (though it's not exactly _damaging_ you either, a basically-free simplification of the code's worth pursuing).
Alex Martelli
__slots__ assignment has been removed ... works great! Thanks, again.
JaysonFix