Search code examples
pythonpython-3.xsyntax-errorself

Self in Python Syntax Error: Invalid Syntax, String's Attributes Inexisting?


I have a little problem here; how do I make a self argument in Python? I want to be able to create an function that works like this:

'Hello, World!'.Write()

or at least something close to that. This is my code so far:

def Write(self):
  print(self)
'Hello, World!'.Write()

I got this as a syntax:

  File "main.py", line 3, in <module>
    'Hello, World!'.Write()
AttributeError: 'str' object has no attribute 'Write'
python3 exited with code 1...

so I tried changing the last line to Write.'Hello, World!'() instead. Now I have another error:

File "main.py", line 3
    Write.'Hello, world!'()
                        ^
SyntaxError: invalid syntax
python3 exited with code 1...

Something definitely isn't working. Did I miss one or a few steps? Is there something I am not seeing? Should I even use self?


Solution

  • Under normal circumstances, you can't add methods to an existing builtin object. Instead, the simple approach is to write a function that accepts the object you want to operate on:

    def write(self):
        print(self)
    

    You can call an argument whatever you want, including self. Now you can call it like this:

    write('Hello World!')
    

    If you were dealing with classes defined in Python rather than a builtin like str, you could try monkey-patching your method right in:

    class MyType:
        def __init__(self, value):
            self.value = value
    

    To monkey-patch the class, so all instances see the method:

    MyType.write = write
    MyType('Hello World!').write()
    

    To monkey-patch just a single instance:

    instance = MyType('Hello World!')
    instance.write = write.__get__(instance)
    instance.write()
    

    All that being said, the proper approach to modifying existing classes with new functionality is to subclass. You are free to extend str with any functionality you see fit:

    class MyType(str):
        def write(self):
            print(self)
    

    The only thing that will differ from your example is that your class is not special and can no longer be initialized from a literal. In all other respects, it will behave like a string with a write method:

    s = MyType('Hello World!')
    s.write()