This question already has answers here:
Adding a method to an existing object instance in Python
(19 answers)
Closed 7 years ago.
In my model I have a class containing a rather generic function, which calls a higher order function. I put together a simple example of it:
class AClass(object):
def __init__(self, prop, fun):
self.prop = prop
self.fun = fun
def do_sth(self):
self.fun()
def namely_this_(context):
print 2*context.prop
obj1 = AClass(3, namely_this_)
obj1.do_sth()
This snippet contains everything to know, just note, that it could be continued by something like:
def namely_this_2(self):
print 4*self.prop
obj2 = AClass(2, namely_this_2)
obj2.do_sth()
The above code does not run, instead it throws a
TypeError: namely_this_() takes exactly 1 argument (0 given)
Instead, I have to change the do_sth to
def do_sth(self):
self.fun(self) # the *self* in the parenthesis added
Question: In what way does the namely_this_ differ from functions defined inside a class and is my workaround a viable solution?
An instance method is a property of the class, not the instance itself. If you changed your init to assign fun to self.__class__.fun, it would work; except then of course all instances would share the same function, which is clearly not what you want.
In order to make it an actual method, you need to make it an instance of types.MethodType:
def __init__(self, prop, fun):
self.prop = prop
self.fun = types.MethodType(fun, self)
Related
This question already has answers here:
How can I access "static" class variables within methods?
(6 answers)
Closed 3 years ago.
class MyClass(object):
code_mapping = {...}
def get_name(code):
code = code_mapping[code]
...
In this piece of code, it complains that 'code_mapping is not defined'. Isn't code_mapping is accessible to everything within MyClass?
Initialize it with self. This will make it accessible by any function in the class by passing it with self.<variable> and then passing self as a function argument to anything you want to pass the variable to.
class MyClass(object):
def __init__(self):
self.code_mapping = {...} # if this will be a hard coded
def get_name(self):
code = self.code_mapping[code]
...
Or you could do:
class MyClass(object):
def __init__(self, code_mapping):
self.code_mapping = code_mapping
def get_name(self):
code = self.code_mapping[code]
...
if you'd like to pass some code mapping as an argument to your class at its instantiation.
To create a class object from this where you want {'code1' : 'name'} you then initiate a class object like this:
code1 = MyClass({'code1' : 'name'})
And then {'code1' : 'name'} will be what is carried forth into whatever get_name() does and the value of code in get_name will be name.
This question already has an answer here:
Assign external function to class variable in Python
(1 answer)
Closed 3 years ago.
In my class I'd like to call a non-member function whose reference is stored in a member variable. My issue is that it tries to pass self to the function as the first argument. How can I avoid this?
class MyClass:
my_useful_static_function = crcmod.mkCrcFun(0x11021, True)
def __init__(self):
# this gets called with the first argument as self :(
result = self.my_useful_static_function()
Use staticmethod:
class MyClass:
my_useful_static_function = staticmethod(crcmod.mkCrcFun(0x11021, True))
def __init__(self):
result = self.my_useful_static_function()
You need to use staticmethod like so:
class Foo:
#staticmethod
def my_method():
print("This is a static method")
def my_other_method(self):
print("This is not static")
# This works
Foo.my_method()
# This won't work
Foo.my_other_method()
# This works though
foo_instance = Foo()
foo_instance.my_other_method()
This question already has answers here:
Python NameError: name is not defined
(4 answers)
Closed 4 years ago.
class one(object):
b=squares
def squares(self):
print('hi')
getting the following error:
NameError: name 'squares' is not defined
This should work for you. Let me explain it. First code should go inside of methods, these methods can be combined into classes. You shouldn't place code in the class directly.
In Python when an object is instantiated the __init__(self) method is called directly. This method takes the self argument which will hold the attributes and functions available for this class. In our case, I added an attribute called self.size = 5. Then we call the squares(self) function. Notice we access it as self.function_name().
Then in that function we pass the self argument. Notice how we can access the self.size attribute from this function.
class one(object):
def __init__(self):
self.size = 5
b = self.squares()
def squares(self):
print('hi' + str(self.size))
o = one()
If you want a generic function not tied to your object. Then you need to define it before the class.
def squares(a):
return a*a
class One():
def __init__(self, a):
self.num = a
self.example()
def example(self):
b=squares(self.num)
print(b)
obj = One(4)
This question already has answers here:
How to overload __init__ method based on argument type?
(10 answers)
Closed 7 years ago.
I have two constructors in one class, but when I call one of them (a one with one argument - only self - instead of a one with 4 arguments), it results in an error, saying it expected more arguments than the 1 given.
The class is the following way:
class Message:
def __init__(self):
self.data = None
def __init__(self, type, length, data):
self.type = type
self.length = length
self.data = data
and the call to it (where I also get the error is at):
msg = Message()
Where might be the problem? Isn't it comparable to C++? If not, how can I still get the same result in another way?
You cannot have two __init__ methods in a single class.
What your code effectively does is override the first method so it is never used, then you get an error because you haven't supplied enough arguments.
One way to get around this would be to supply default values using keyword-arguments. In this way if you create the Message object with no values, it'll use the defaults. The example below uses None as the default value but it could be something more complex:
class Message(object):
def __init__(self, type=None, length=None, data=None):
self.type = type
self.length = length
self.data = data
Python doesn't work that way. Use this:
class Message:
def __init__(self, type=None, length=None, data=None):
self.type = type
self.length = length
self.data = data
I know that this is super basic Python stuff, but the concept doesn't get into my mind.
I miss the fundamental reason and the structure to instantate an object under __init__()
This is a basic example, I do not understand the reason to put there self.tangerine="..." and why if I add self.order="order" everything works properly even if this parameter is not added into __init__(self, order)
class MyStuff(object):
def __init__(self):
self.tangerine="And now a thousand years between"
def apple(self):
print "I AM CLASSY APPLE!"
thing=MyStuff()
thing.apple()
print thing.tangerine
So to drill down on this simple example, I added a variable in init:
class MyStuff(object):
def __init__(self, order):
self.tangerine="And now a thousand years between"
self.order="order"
def apple(self):
print "I AM CLASSY APPLE!"
thing=MyStuff()
thing.apple()
print thing.tangerine
Now I get an error:
Traceback (most recent call last):
File "ex40_a.py", line 11, in <module>
thing=MyStuff()
TypeError: __init__() takes exactly 2 arguments (1 given)
Thought it seems to me that there are 2 arguments there (tangerine(self) and order).
Can anybody help me?
Anatomy of your second code snippet:
# Define class named MyStuff which inherits from object
class MyStuff(object):
# Define initializer method for class MyStuff
# This method accepts 2 arguments: self and order
# self will hold newly created instance of MyStuff
def __init__(self, order):
# Assign a string value to field tangerine of current instance
self.tangerine="And now a thousand years between"
# Assign a string value to field order of current instance
self.order="order"
# Note that second argument (order) was not used
# Define apple method for class MyStuff
# This method accepts 1 argument: self
# self will hold the instance of MyStuff
def apple(self):
# Print a string to standard output
print "I AM CLASSY APPLE!"
# Create instance of MyStuff
# Initializer is called implicitly and self is set to new instance
# Second argument (order) is missing, so you get exception
thing=MyStuff()
# Correct invocation would be
thing = MyStuff("some string value")
# Call method apple of MyStuff instance - statement correct but won't be reached
# due to former exception
thing.apple()
# Print value of field tangerine of MyStuff instance to standard output - again
# statement correct but won't be reached due to former exception
print thing.tangerine
Things to read about:
- actual and formal function/method parameters
- string literals
- and of course Python classes
Looks ok but I assume you want the order value fed into your object.
Also, generally you dont want to use print statements on your classes, instead return them and then print them else where in your code if you need
class MyStuff(object):
def __init__(self, order):
self.tangerine = "And now a thousand years between"
self.order = order
def apple(self):
return "I AM CLASSY APPLE!"
thing = MyStuff("I like strings and integer values")
print thing.order
print thing.tangerine
print thing.apple()
Output:
I like strings and integer values
And now a thousand years between
I AM CLASSY APPLE!
you specify the parameters you want to call your class with this:
def __init__(self, order):
self.order = order
if you dont want to call your class with anything and just use the string value do this:
def __init__(self):
self.order = "order"