0

I have this class:

class A(str):            
    def __str__(self):
        return "the string"
    
    def __repr__(self):
        return "the repr"

a = A("change me")

Running print a returns the string

Running repr(a) returns the repr

Running a returns change me

The problem

Running the instance a returns the string used to instantiate the class. How can I change this string in the instance after instantiation?

The returns of __str__ and __repr___ are not the problem, as in certain situations rather than calling these methods the instance is called directly. So where you may expect __repr__ to return, the instance returns the instantiation string instead.

I have been unable to find any attributes within the string class to change this. Most solutions I've tried require you to re-instance the a variable, which I don't want to do. I want to change the string from within the current instance of the object class variable.

I have tried rebuilding the class through methods utilising __new__ and type(). However, this seems to require re-instancing the stored class variable, as recreating the class creates a duplicate and does not update the current instance.

I am limited to using Python 2.7, due to pipeline constraints.

Adam Sirrelle
  • 357
  • 8
  • 18
  • Do you basically want a mutable string subclass? If so, do either of the following answer your question? [1](https://stackoverflow.com/questions/4520298/modify-subclassed-string-in-place) [2](https://stackoverflow.com/questions/10572624/mutable-strings-in-python) – bgfvdu3w Jul 13 '22 at 05:44
  • The 1st reference didn't work for me; using `StringIO` returns an `instance` when running `a`, `<__main__.DelimitedStringIO instance at 0x00000245933C8788>`. However the 2nd link you provided might be working for me... – Adam Sirrelle Jul 13 '22 at 06:10
  • Ah, no. :/ Subclassing this as an `Object` returns the object class instance MutableString rather than a string, as a subclass of `string` would. Thanks for the suggestion! – Adam Sirrelle Jul 13 '22 at 06:16
  • Since you're using Python 2, `UserString.MutableString` is available. Have you tried that? – bgfvdu3w Jul 13 '22 at 17:56

1 Answers1

0

I have a potential answer, although it feels VERY bad and hacky.

class A(str):            
    def __str__(self):
        return "the string"

    def __repr__(self):
        return "the repr"
    
    def _instance_name(self):
        return [k for k, v in globals().items() if v is self]
    
    def change(self, new_string):
        name = self._instance_name()

        if name:
            globals()[name[0]] = type('A', (A, ), self.__dict__)(new_string)

a = A("change me")

Running a returns change me

a.change("I have changed")

Running a returns I have changed

Changing globals this way feels like welcoming the end times, but it's the only solution I've found so far. Any other potential methods would be appreciated!

Adam Sirrelle
  • 357
  • 8
  • 18