using https://github.com/clarete/forbiddenfruit

from forbiddenfruit import curse
def ispalendrome(self): #note that self is really just a variable name ... it doent have to be named self
    return self == self[::-1]
curse(str, "ispalendrome",ispalendrome)

"hello".ispalendrome()

note that just because you can does not mean its a good idea

alternatively it is much better to just do

def ispalendrome(a_string):
    return a_string == a_string[::-1]

ispalendrome("hello")
Answer from Joran Beasley on Stack Overflow
Top answer
1 of 6
5

using https://github.com/clarete/forbiddenfruit

from forbiddenfruit import curse
def ispalendrome(self): #note that self is really just a variable name ... it doent have to be named self
    return self == self[::-1]
curse(str, "ispalendrome",ispalendrome)

"hello".ispalendrome()

note that just because you can does not mean its a good idea

alternatively it is much better to just do

def ispalendrome(a_string):
    return a_string == a_string[::-1]

ispalendrome("hello")
2 of 6
3

It feels like you want to monkey patch a method onto this. If so, then welcome to the dark side young one. Let us begin the cursed ritual. In essence you want to monkey patch. All we need is a little monkey blood. Just kidding. We need type.MethodType. But note, that you cannot monkey patch stdlib types:

>>> from types import MethodType
>>> def palindrome(self): return self == self[::-1]
...
>>> str.palindrome = MethodType(palindrome, str)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: can't set attributes of built-in/extension type 'str'

But that won't stop you from causing havoc in other classes:

>>> class String(object):
...     def __init__(self, done):
...         self.done = done
...
...
...
>>> s = String("stanley yelnats")
>>> def palindrome(self): return self.done[::-1]
>>> s.palindrome = MethodType(palindrome, s)
>>> s.palindrome()
'stanley yelnats'

You see how easy that was? But we're just getting started. This is just a mere instance lets kill a class now shall we? The next part will get you laughing maniacally:

>>> from types import DynamicClassAttribute
>>> class String(object):
...     def __init__(self, done):
...         self.done = done
...
...
...
>>> s = String("cheese")
>>> def palindrome(self): return self.done[::-1];
...
>>> String.palindrome = DynamicClassAttribute(palindrome)
>>> s.palindrome
'eseehc'

After this, if you do not feel evil. Then you must come over to my evil lair, where I shall show you more evil tricks and share cookies.

Discussions

python - Using self in class function defined outside of class - Stack Overflow
I'm working on a project where I have a class that accepts a function in its __init__ like the following class Example: def __init__(self, func,param1,param2): self.function=func More on stackoverflow.com
🌐 stackoverflow.com
class - Python calling method without 'self' - Stack Overflow
There might be another function with the same name outside your class. self is an object reference to the object itself, therefore, they are same. Python methods are not called in the context of the object itself. self in Python may be used to deal with custom object models or something. More on stackoverflow.com
🌐 stackoverflow.com
python - Passing a class's "self" to a function outside it such that the class's variables are accessible and modifiable? - Stack Overflow
Can I pass the self instance variable of the class from within the class to some helper function outside the class? For example, will the following work when an object of SomeClass is initialized? Isn't there any type casting required? Is this coding style reliable? Is there any possibility of this feature being dropped off in future releases of Python ... More on stackoverflow.com
🌐 stackoverflow.com
October 20, 2016
When do you use 'self' in Python? - Stack Overflow
Using Oskarbi's example, if you ... not as instance.my_method(self, some_var). You reference a class attribute from outside an instance method but inside the class definition. You're inside a staticmethod. These don'ts are just examples of when not to use self... More on stackoverflow.com
🌐 stackoverflow.com
Top answer
1 of 2
4

The way you define your decorator the target object information is lost. Use a function wrapper instead:

def CalcOrPass(func):
    @wraps(func)
    def result(self, *args, **kwargs):
        res = self.stats[func.__name__]
        if not res:
            res = func(self, *args, **kwargs)
            self.stats[func.__name__] = res
        return res
    return result

wraps is from functools and not strictly necessary here, but very convenient.


Side note: defaultdict takes a factory function argument:

defaultdict(lambda: None)

But since you're testing for the existence of the key anyway, you should prefer a simple dict.

2 of 2
2

You can't do what you want when your function is defined, because it is unbound. Here's a way to achieve it in a generic fashion at runtime:

class CalcOrPass(object):
    def __init__(self, func):
        self.f = func

    def __get__(self, obj, type=None): # Cheat.
        return self.__class__(self.f.__get__(obj, type))

    #if the value is already in the instance dict from SimpleData,
    #don't recalculate the values, instead return the value from the dict
    def __call__(self, *args, **kwargs):
        # I'll concede that this doesn't look very pretty.
        # TODO handle KeyError here
        res = self.f.__self__.stats[self.f.__name__]
        if not res:
            res = self.f(*args, **kwargs)
            self.f.__self__.stats[self.f__name__] = res
        return res

A short explanation:

  • Our decorator defines __get__ (and is hence said to be a descriptor). Whereas the default behaviour for an attribute access is to get it from the object's dictionary, if the descriptor method is defined, Python will call that instead.
  • The case with objects is that object.__getattribute__ transforms an access like b.x into type(b).__dict__['x'].__get__(b, type(b))
  • This way we can access the bound class and its type from the descriptor's parameters.
  • Then we create a new CalcOrPass object which now decorates (wraps) a bound method instead of the old unbound function.
  • Note the new style class definition. I'm not sure if this will work with old-style classes, as I haven't tried it; just don't use those. :) This will work for both functions and methods, however.
  • What happens to the "old" decorated functions is left as an exercise.
🌐
Edureka
edureka.co › blog › self-in-python
Self in Python Class | What is the Use of Python Self?
December 5, 2024 - For defining global fields or the ... them outside the class methods. This video talks about the Top 10 Trending Technologies in 2025 that you must learn. self is used in different places and often thought to be a keyword. But unlike in C++, self is not a keyword in Python...
🌐
Python
peps.python.org › pep-0673
PEP 673 – Self Type - Python Enhancement Proposals
November 10, 2021 - We reject type aliases containing Self. Supporting Self outside class definitions can require a lot of special-handling in type checkers. Given that it also goes against the rest of the PEP to use Self outside a class definition, we believe the added convenience of aliases is not worth it:
Find elsewhere
🌐
Medium
medium.com › edureka › self-in-python-fb23ccc0c0bd
What is the use of self in Python?
June 28, 2021 - That variable is simply existent only while that method is running and hence, is local to that method. For defining global fields or the variables of the complete class, we need to define them outside the class methods. self is used in different places and often thought to be a keyword. But unlike in C++, self is not a keyword in Python.
🌐
Python documentation
docs.python.org › 3 › tutorial › classes.html
9. Classes — Python 3.14.8 documentation
1 week ago - Any function object that is a class attribute defines a method for instances of that class. It is not necessary that the function definition is textually enclosed in the class definition: assigning a function object to a local variable in the class is also ok. For example: # Function defined outside the class def f1(self, x, y): return min(x, x+y) class C: f = f1 def g(self): return 'hello world' h = g
🌐
Finxter
blog.finxter.com › define-a-method-outside-of-the-class-definition
Define A Method Outside Of The Class Definition – Be on the Right Side of Change
March 29, 2022 - There’s another way to define the function outside of a class and then further add it. But there is a difference in assigning the function to the instance object or the class. Look at the following example to understand the subtle difference: class Demo1(object): def __init__(self, bar): self.func = 'Finxter' Demo1.funcbar = bar class Demo2(object): def __init__(self, bar): self.func = 'Finxter' self.funcbar = bar def bar(self): return 'Welcome' + self.func
🌐
Medium
medium.com › quick-code › understanding-self-in-python-a3704319e5f0
Understanding self in Python. Once you start using Python, there is… | by Ashan Priyadarshana | Quick Code | Medium
May 30, 2021 - Instance variables, on the other ... owns its instance variables). So typically values of instance variables differ from instance to instance. Class variables in python are defined just after the class definition and outside of any methods:...
Top answer
1 of 2
1

It is a perfectly fine use case. By the way, note that you're overriding the builtin list.

2 of 2
1

To use self, you have to share a list collection between instances of a Person-class. In that case this collection should be declared as a class attribute or global list variable (not an instance attribute).

These samples of code are working:

with global list variable:

class Person:

    def __init__(self, name):
        self.name = name

    def make_friends(self, list):
        list.remove(self)

    def __repr__(self):
        return self.name


p1 = Person("Joe")
p2 = Person("Barack")

the_list = []
the_list.append(p1)
the_list.append(p2)

p1.make_friends(the_list)

print(the_list)

With class attribute:

class Person2:
    class_list = []

    def __init__(self, name):
        self.name = name
        Person2.class_list.append(self)

    def make_friends(self):
        Person2.class_list.remove(self)

    def __repr__(self):
        return self.name


p1 = Person2("Joe")
p2 = Person2("Barack")
print(Person2.class_list)
p1.make_friends()
print(Person2.class_list)

EDIT: Variable 3 when a list of people is inside another class. For accessing a list inside another class you could use attribute name or public method to get it if implemented:

class ClassWithList:
    def __init__(self):
        self.list_collection = []

    def get_list(self):
        return self.list_collection


class_with_list = ClassWithList()


class Person:

    def __init__(self, name):
        self.name = name

    def make_friends(self, list):
        list.remove(self)

    def __repr__(self):
        return self.name


p1 = Person("Joe")
p2 = Person("Barack")
# using implemented get-method of instance list attribute
class_with_list.get_list().append(p1)
class_with_list.get_list().append(p2)
print(class_with_list.get_list())
p1.make_friends(class_with_list.get_list())

print(class_with_list.get_list())

# instance list attribute of class`ClassWithList
print(class_with_list.list_collection)
p2.make_friends(class_with_list.list_collection)
print(class_with_list.list_collection) 
🌐
GeeksforGeeks
geeksforgeeks.org › python › self-in-python-class
self in Python - GeeksforGeeks
July 4, 2026 - Here, this is used instead of self. The program works correctly because Python does not require the parameter name to be self. However, using self is recommended because it is the standard convention. self parameter refers to the object that calls a method. It allows Python to identify and work with the attributes and methods of that specific object. ... class Check: def __init__(self): print("Address of self:", id(self)) obj = Check() print("Address of object:", id(obj))
🌐
Quora
quora.com › When-I-create-a-Python-method-without-creating-a-class-I-dont-need-to-define-self-as-a-default-method-parameter-but-when-I-put-the-method-in-a-class-I-need-to-put-self-Why-is-this
When I create a Python method without creating a class, I don't need to define 'self' as a default method parameter, but when I put the method in a class I need to put 'self'. Why is this? - Quora
When I create a Python method without ... I need to put 'self'. Why is this? ... Associate Professor of Computer Science at CSUMB · Author has 35.9K answers and 586.4M answer views · 4y · In Python, methods can exist inside of a class (sort of) or outside of a clas...
🌐
Educative
educative.io › answers › what-is-self-in-python
What is self in Python?
Common mistakes when using self in Python include: Forgetting to include self as the first parameter in instance methods. Using non-standard names for self (e.g., self_var). Accessing class variables with self instead of the class name. Not using self for instance variables, causing local variables instead. Reassigning self within methods, breaking the reference to the instance. Using self in class methods instead of cls. Trying to access self outside the class without creating an instance.
🌐
Quora
quora.com › In-python-when-can-I-write-a-method-without-self-as-its-argument-and-where-is-it-used
In python, when can I write a method without self as it's argument and where is it used? - Quora
Answer: Self argument in class passes reference of object which has called that method. Every object has it’s own data, so it is require to tell method that which instance of class it will work with. It will generate an error unless you will specify which instance to work with.