Joyte
Joyte

Reputation: 75

Is there a way to change a class variable without adding 'foo = '?

I have a class, and would like to change an object of it (similar to the pop method of lists), without adding an foo = foo.bar()

In simpler terms, i'd like to do foo.bar() instead of foo = foo.bar(). Is this possible in python? Here's some code that i have, which hopefully furthers understanding:

class mystr(str):
    def pop(self, num):
        self = list(self)
        changed = self.pop(num)  # The particular character that was removed
        self = ''.join(self)  # The rest of the string
    
        # Somewhere in here i need to be able to change the actual variable that pop() was called on

        return changed  # Emulates python lists' way of returning the removed element.


my_var = mystr("Hello World!")
print(my_var.pop(4)  # Prints 'o', as you would expect
print(my_var)  # But this still prints 'Hello World!', instead of 'Hell World!'
# It isn't modified, which is what i want it to do

Upvotes: 0

Views: 333

Answers (2)

Tomerikoo
Tomerikoo

Reputation: 19414

You could achieve that by encapsulating a string, rather then inheriting from it:

class mystr:
    def __init__(self, string):
        self._str = string

    def pop(self, num):
        string_list = list(self._str)
        changed = string_list.pop(num)  # The particular character that was removed
        self._str = ''.join(string_list)  # The rest of the string

        return changed  # Emulates python lists' way of returning the removed element.

    def __repr__(self):
        return self._str

Running the same code with this class instead will print:

o
Hell World!

Upvotes: 0

user2357112
user2357112

Reputation: 280778

You can, but not with str.


What you're looking for is a way to mutate your object. For most classes you write yourself, doing that is straightforward:

class Foo:
    def __init__(self):
        self.stuff = 0
    def example(self):
        self.stuff += 1

Here, calling example on a Foo instance mutates it, by changing its stuff instance attribute.


str, however, is immutable. It stores its data in C-level data structures and provides no mutator methods, so there's no way to modify its data. Even if you used ctypes to bypass the protection, you'd just get a bunch of memory corruption bugs.

You can add your own attributes in a subclass, and those will be mutable, but if you do that to fake a mutable string, you might as well just not inherit from str. Inheriting from str in that case will only cause bugs, with some code looking at your "fake" data and other code looking at the "real" underlying str data.


Most likely, the way to go will be one of two options. The first is to just use regular strings without your subclass or the methods you want to add. The second is to write a class that doesn't inherit from str.

Upvotes: 2

Related Questions