Forum Archive

Basic python question about classes

ihf

I realize that this is not a Pythonista question per se but perhaps someone here can help. If I have a function which uses the google api to translate from one language to another, is there a way to add this function as a method to the builtin str object? In particular, if the function is called 'trans' (there is a builtin translate which I don't wish to replace), is there a way to make the following work:

'hello, how are you'.trans() #assume a target language if not specified

ihf

Further reading suggests that this is not possible in Python.

henryiii

You can subclass str, or you can simply make it a function, but no, you can't change the meaning of 'stuff' to be something other than str. It would be, at best, myStr('hello, how are you').trans() or trans('hello, how are you')

(At least, to the best of my knowledge)

ihf

Yes, that seems consistent with what I've found...I can subclass but I cannot add methods to a builtin type. Some other OO languages permit this but apparently Python doesn't.

ihf

It appears that there is a way to do this but it does not work in Pythonista (cannot import ctypes).

Forbidden Fruit

Zoot

Yes, I'm waiting for someone to do a Ruby app like Pythonista, since it's the best language for doing crazy stuff like this, but for writing/using real world software that I want to be reliable, I now really appreciate that Python doesn't allow this sort of thing and has nice strong namespaces that keep modules blissfully isolated in most cases.

Still want to be able to buy a Rubynista app tho.

Z.

[deleted]

I thought researching this would be a good way to learn about builtin types, attributes, etc. I found http://stackoverflow.com/questions/7255655/ the most help. It seems that whilst it's not the full answer sought, its possible to go one further than a subclass of str, myStr('hello, how are you').trans(), which would return str, not myStr, on str methods. Some of the examples I found weren't printable or weren't consistent in returning the new type, hopefully the example below is. It's a subclass just of 'object' but it passes on method calls to str and ensures that any str result is converted to strT

class strT(object):
    def __init__(self, value):
        self.value = value

    def __getattr__(self, attr):
        attrib = getattr(self.value, attr)
        if not callable(attrib):
            return attrib
        def wrapper(*params, **args):
            result = attrib(*params, **args)
            if type(result) is str:
                return strT(result)
            return result
        return wrapper

    def trans(self):
        return strT(self.value + ' is hola')

    def __str__(self): 
        return self.value

print strT(' HELLO ').strip().trans().lower()
[deleted]

This approach seems to be a further advance... creating a subclass of str that behaves as above and supports indexing too...

class strT(str):

    def __getattribute__(self, attr):
        attrib = super(strT, self).__getattribute__(attr)
        if not callable(attrib):
            return attrib
        def wrapper(*params, **args):
            result = attrib(*params, **args)
            if type(result) is str:
                return strT(result)
            return result
        return wrapper

    def trans(self):
        return strT(self + ' is hola')

print strT(' HELLO ').strip().trans().lower()[0:13]