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 Overflowusing 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")
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.
After the call сlass you need to put parenthesis (Dog(), not Dog):
Marley = Dog()
Marley.Bark()
Seems like you're missing a little part. I've noticed that you are calling a function improperly. Don't forget to type the opening and closing brackets while calling a function. The correct way would be;
class Dog():
def Bark(self):
print("woof")
def Bark_lots(self):
for I in range(3):
self.Bark()
Marley = Dog()
Marley.Bark_lots()
python - Using self in class function defined outside of class - Stack Overflow
class - Python calling method without 'self' - Stack Overflow
python - Passing a class's "self" to a function outside it such that the class's variables are accessible and modifiable? - Stack Overflow
When do you use 'self' in Python? - Stack Overflow
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.
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 likeb.xintotype(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.
Also you can make methods in class static so no need for self. However, use this if you really need that.
Yours:
class bla:
def hello(self):
self.thing()
def thing(self):
print "hello"
static edition:
class bla:
@staticmethod
def hello():
bla.thing()
@staticmethod
def thing():
print "hello"
One reason is to refer to the method of that particular class's instance within which the code is be executed.
This example might help:
def hello():
print "global hello"
class bla:
def hello(self):
self.thing()
hello()
def thing(self):
print "hello"
b = bla()
b.hello()
>>> hello
global hello
You can think of it, for now, to be namespace resolution.
Adding an answer because Oskarbi's isn't explicit.
You use self when:
- Defining an instance method. It is passed automatically as the first parameter when you call a method on an instance, and it is the instance on which the method was called.
- Referencing a class or instance attribute from inside an instance method. Use it when you want to call a method or access a name (variable) on the instance the method was called on, from inside that method.
You don't use self when
- You call an instance method normally. Using Oskarbi's example, if you do
instance = MyClass(), you callMyClass.my_methodasinstance.my_method(some_var)not asinstance.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. The dos are when you should use it.
Use self to refer to instance variables and methods from other instance methods. Also put self as the first parameter in the definition of instance methods.
An example:
class MyClass(object):
my_var = None
def my_method(self, my_var):
self.my_var = my_var
self.my_other_method()
def my_other_method(self):
# do something...
It is a perfectly fine use case. By the way, note that you're overriding the builtin list.
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)
Ik this is a basic question but I'm just learning to code and I'm learning about classes. For whatever reason I cannot understand or grasp the use of the self variable in fictions of classes. Hopefully someone's explanation here will help me...