-3

I have trouble resolving a recursion issue, how can I build a class which would behave like this:

  • print the requested attributes from it: o.foo.bar would print "o.foo.bar" when called.
  • same thing for a function: o.foo.bar(True) -> "o.foo.bar(True)".
  • this attribute call will return a value when called, for example "1".

Code would look like:

>>> o = MyClass()
>>> result = o.foo.bar
"o.foo.bar"
>>> print(result)
1

I've tried some things with __getattr__ but I cannot manage to handle recursion correctly, I cannot get when the end of the nested chain has been reached and then return the result accurately.

That's the closest I got:

class MyClass:
    def __init__(self):
        self.a = []

    def __getattr__(self, name):
        self.a.append(name)
        print(self.a)
        return self

o = MyClass()
result = o.foo.bar

PURPOSE

This is a simplified code to get rid of context complexity. I'm currently trying to wrap the JS API of Photoshop and this could help calling the software functions by writing same API functions in Python. The print would be replaced by a call to the PS Server and the result by the actual result of the call.

11
  • 1
    It sounds like your use case is best served by not doing this. One obvious alternative is, why not just pass 'o.foo.bar' to the Photoshop API the straightforward way instead of going through all this? Commented Apr 22 at 9:52
  • Because a photoshop python api exists, with some helpful functions, but it works only for windows (relies on COM). What I'm trying to do is to fake the behavior of the COM class but using server calls to make it usable on OSX. This way it'll be usable without a full rewriting. Commented Apr 22 at 9:59
  • That still doesn't sound like your chosen approach makes sense. If you want to write an API wrapper, that should involve specific wrappers for the actual contents of the API, not this. Commented Apr 22 at 10:02
  • I maybe being completely brain twisted for now about this, but I don't see why this approach isn't relevant. I've gone through the whole python PS API and I'm pretty sure it'd would work fine. Maybe it is not something possible to achieve in Python, and that's why I'm asking this. Commented Apr 22 at 10:09
  • All you're doing here is generating strings that look like simple Python expressions. Not even strings that look like Javascript - you're generating strings that look like Python. Strings that are essentially identical to whatever Python code the programmer typed out. That doesn't actually provide any value for the user of your code - they could have just written the strings themselves. Commented Apr 22 at 10:17

1 Answer 1

2

The major issue here is you cannot call o.foo.bar, because a function object's attribute are only accessed when :

  • They're defined as instance attributes (self.bar)

  • The method defining the attribute has been called beforehand, bringing it to existence

class MyClass():
    def foo(self):
        self.bar='bar'#defined as instance attribute

o = MyClass()
print(o.foo())#method call <=> bar definition
print(o.bar)#bar accessed properly

So you cannot truly reach your goal here, because the basic logic of attribute access within a class is not respected when you type in o.foo.bar.

Sign up to request clarification or add additional context in comments.

2 Comments

That's what I was afraid of, thank you!
It was a pleasure :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.