1

I have two objects i sub-classed from the str and int classes, to which i add a revert method, which can turn one object to the other:

class newString(str):
    ...
    ...
    def revert(self, distance, obj):
        self = newInt(self)
class newInt(int):
    ...
    ...
    def revert(self):
        self = newString(self)

a = newInt(2)
a.revert()
print(type(a))

#output
<class "newString">

I know the "self" keyword can't be used this way but i put it like this for illustration. I want the object to be able to change itself to another, is this possible without having to use a return statement in the "revert" method? Because if i used a return statement it would mean I have to assign the the returned object back to a again and the syntax will be something like:

class newString(str):
    ...
    ...
    def revert(self):
        new = newInt(self)
        return new
class newInt(int):
    ...
    ...
    def revert(self):
        new = newInt(self)
        return new

a = newInt(2)
a = a.revert()
print(type(a))

#output
<class "newString">

which has always seemed a bit clumsy to me, thank you ;)

what I've tried: I've tried simulating passing by reference; example:

class newString(str):
    ...
    ...
    def revert(self, obj):
        obj[0] = newInt(obj[0])
class newInt(int):
    ...
    ...
    def revert(self, obj):
        obj[0] = newInt(obj[0])

a = newInt(2)
a.revert([a])
print(type(a))

#output
<class "newString">

but again, clumsy. since i have to wrap the variable in a list to make it mutable before passing it to the method. Any help is appreciated, thank you.

Tochi Bedford
  • 354
  • 1
  • 9
  • Side note: `self` is neither a property of a class (it gets passed into methods) nor a keyword. And it's only called `self` by convention, though I strongly recommend that you use that name too. – ChrisGPT was on strike Jul 28 '20 at 12:17
  • 2
    "I want the object to be able to change itself to another"—why? – ChrisGPT was on strike Jul 28 '20 at 12:19
  • i sort of misused the word "keyword" there actually, for lack of a better name. – Tochi Bedford Jul 28 '20 at 12:26
  • reason for this is i was having a go at creating varibles that store their own history as they change, repo here : https://github.com/tochibedford/stateful; so the revert method will allow them go backwards to a previous "state" – Tochi Bedford Jul 28 '20 at 12:27

2 Answers2

3

I wouldn't go down that rabbit hole. Even if assigning back to self would have worked, it would be a nightmare to debug and maintain.

I'd use classmethods to allow creating one type from another. Assigning back is not more clumsy than secretly changing types under the hood.

classmethods are the idiomatic way to create objects of a certain type from objects of another type in Python. It is essentially a "workaround" for the fact that Python does not support constructor overloading (or any method overloading, for that matter).

Explicit is better than implicit.

class newString(str):
    @classmethod
    def from_newInt(cls, new_int_obj):
        return cls(str(new_int_obj))


class newInt(int):
    @classmethod
    def from_newString(cls, new_string_obj):
        return cls(int(new_string_obj))

s = newString('1')
i = newInt(1)
print(type(newString.from_newInt(i)))
print(type(newInt.from_newString(s)))
# <class '__main__.newString'>
# <class '__main__.newInt'>
DeepSpace
  • 78,697
  • 11
  • 109
  • 154
0

This is not how objects work. self is a reference to an object. Even if you change it in a function-scope, that is not a change to the object itself. You should learn more about object-oriented programming and what is an object and why it is not ought to change dynamically its type.

However, you can use @staticmethod and @staticmethod annotated static or class methods that can return a new object created from a type that you want.

Or another option would be to create a method something like to_mystr that operated on a given object and returns an object that is created from your object (converted to another type).

Janekx
  • 631
  • 6
  • 21
  • yes, but returning a new object and having to re-assign it to a new variable is what i'm trying to avoid – Tochi Bedford Jul 28 '20 at 12:34
  • 1
    In my opinion it is not avoidable. I'm not really into that but maybe you could write a library in c that can rewrite a chunk of memory. – Janekx Jul 28 '20 at 12:57