Check existence of members/methods

N

Nicolas Fleury

Hi everyone,
I'm wondering what is the easiest/cleanest way to look for existence of
available methods/members.

For example, in parsing a xml file, created objects can define a
setXmlFilename function or a xmlFilename member to get the filename they
are from.

Right now I have the following code:

try: object.setXmlFilename
except:
try: object.xmlFilename
except: pass
else: object.xmlFilename = currentFilename
else: object.setXmlFilename(currentFilename)

But it looks a bit wierd, since it's like a "if" with the false
consequence presented first. I wonder if there is, and if there should
be a better way to do it. I could also do the following:

def noraise(expressionString):
try: eval(expressionString)
except: return True
return False

if noraise("object.setXmlFilename"):
object.setXmlFilename(currentFilename)
elif noraise("object.xmlFilename"):
object.xmlFilename = currentFilename

But it puts code in strings, which I feel less natural. What do you
think about it? Have I miss a better solution or is there something for
that in the language?

Regards,
Nicolas
 
N

Nicolas Fleury

Nicolas said:
Hi everyone,
I'm wondering what is the easiest/cleanest way to look for existence
of available methods/members.

For example, in parsing a xml file, created objects can define a
setXmlFilename function or a xmlFilename member to get the filename they
are from.

Right now I have the following code:

try: object.setXmlFilename
except:
try: object.xmlFilename
except: pass
else: object.xmlFilename = currentFilename
else: object.setXmlFilename(currentFilename)

But it looks a bit wierd, since it's like a "if" with the false
consequence presented first. I wonder if there is, and if there should
be a better way to do it. I could also do the following:

def noraise(expressionString):
try: eval(expressionString)
except: return True
return False

if noraise("object.setXmlFilename"):
object.setXmlFilename(currentFilename)
elif noraise("object.xmlFilename"):
object.xmlFilename = currentFilename

In fact, it's even more ugly:

def exists(obj, name):
try: eval("obj." + name)
except: return True
return False

if exists(object, "setXmlFilename"):
object.setXmlFilename(currentFilename)
elif exists(object, "xmlFilename"):
object.xmlFilename = currentFilename
 
E

Erik Max Francis

Nicolas said:
But it puts code in strings, which I feel less natural. What do you
think about it? Have I miss a better solution or is there something
for
that in the language?

Try hasattr.
 
A

Alex Martelli

Nicolas Fleury said:
def noraise(expressionString):
try: eval(expressionString)
except: return True
return False

if noraise("object.setXmlFilename"):
object.setXmlFilename(currentFilename)
elif noraise("object.xmlFilename"):
object.xmlFilename = currentFilename

But it puts code in strings, which I feel less natural. What do you
think about it? Have I miss a better solution or is there something for
that in the language?


try: meth = object.setXmlFilename
except AttributeError: meth = lambda x: setattr(object,'xmlFilename',x)
meth(currentFillename)

This doesn't assume that object.xmlFilename must already exist before
you can set it, which IS implied by your code here quoted -- it just
seems a slightly weird condition to me.

I personally prefer the try/except/else variant:

try: meth = object.setXmlFilename
except AttributeError: object.xmlFilename = x
else: meth(currentFillename)

it seems way simpler to me. However, if you think of objects lacking a
setter method as weird and exceptional ones, I see why this might seem
backwards. Personally, I consider setter methods the anomaly (it's
exactly to avoid them that we have property...:) but I do understand
they're frequently used. If I often had to fight with objects full of
getThis, setThat methods I'd wrap them into a generic wrapper with a
__setattr__ and __getattr__ to be able to use attribute get and set as
common sense and decency require, e.g, something like....:

class MakeSensible:
def __init__(self, obj): self.__dict__['obj'] = obj
def __getattr__(self, name):
methname = 'get' + name[0].uppercase() + name[:1]
return getattr(self.obj,methname)()
def __setattr__(self, name, value):
methname = 'set' + name[0].uppercase() + name[:1]
return getattr(self.obj,methname)(value)

(or, you could build all the needed properties at wrapping time, but
it's unclear if that would be an advantage in performance and it would
surely take a bit more code!-). Having made the object sensible once
and for all, thanks to this wrapper, you wouldn't need to thread
carefully throughout the rest of your application...


Alex
 
N

Nicolas Fleury

Alex said:
try: meth = object.setXmlFilename
except AttributeError: meth = lambda x: setattr(object,'xmlFilename',x)
meth(currentFillename)

This doesn't assume that object.xmlFilename must already exist before
you can set it, which IS implied by your code here quoted -- it just
seems a slightly weird condition to me.

In my case, a xml parser/saving creating objects corresponding to
elements and vice-versa, forcing the existence of members before setting
them makes the code more readable (and avoid a lot of errors). I agree
it would be a weird restriction in other situations.
I personally prefer the try/except/else variant:

try: meth = object.setXmlFilename
except AttributeError: object.xmlFilename = x
else: meth(currentFillename)

it seems way simpler to me. However, if you think of objects lacking a
setter method as weird and exceptional ones, I see why this might seem
backwards. Personally, I consider setter methods the anomaly (it's
exactly to avoid them that we have property...:) but I do understand
they're frequently used. If I often had to fight with objects full of
getThis, setThat methods I'd wrap them into a generic wrapper with a
__setattr__ and __getattr__ to be able to use attribute get and set as
common sense and decency require, e.g, something like....:

Actually, I prefer the "hasattr" solution. I'm thinking of removing the
setter functionality from the parser. If some class needs to do
specific stuff when a member is updated, as you said, the built-in
function property can still be used.

Regards,
Nicolas
 

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
473,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top