How to initialize several methods inside a python object - python

In a Javascript object when I would want to initiate several functions inside an object, say myObject, I would have an init function that would call those methods to me initialized and I would simple call myObject.init(). How would I do this in python? Would the following be ok?
class Test(object):
def __init__(self, arg):
self.arg = arg
def init(self):
self.some_function()
self.some_other_function()
def some_function(self):
pass
def some_other_function(self):
pass
my_test = Test("test")
my_test.init()
Thanks for reading!

Yes. That should work fine. but I would give some other name than init(), as it would be explicit and different from default __init__

Related

Passing class objects to another class method Python

I am trying to understand where my mistake lies and I was hoping you could please help me.
I have this code:
import copy
class FooInd():
def __init__(self):
self.a=1
class Planning():
def foo(self,pop):
print(pop.a)
def main():
ind=FooInd()
Planning.foo(copy.deepcopy(ind))
if __name__ == "__main__":
Planning.main()
However I keep receiving this error:
Planning.foo(copy.deepcopy(ind))
TypeError: foo() missing 1 required positional argument: 'pop'
I believe that the mistake is not in the foo method definition, but in my class initiation of the FooInd, however I have checked the Python documentation for classes and I could not find a solution.
Does anyone have a clue of what could I try or where can I check?
Many thanks in advance!
You call Planning.foo on the class, not an instance of the class. You provided the second argument it requires, but not the self argument.
You have two choices:
Construct a Planning instance to call foo on:
def main():
ind=FooInd()
Planning().foo(copy.deepcopy(ind))
# ^^ Makes simple instance to call on
Make foo a classmethod or staticmethod that doesn't require an instance for self:
class Planning():
#staticmethod # Doesn't need self at all
def foo(pop):
print(pop.a)
I think you meant to instantiate Planning before calling methods on it:
import copy
class FooInd():
def __init__(self):
self.a = 1
class Planning():
def foo(self, pop):
print(pop.a)
def main(self):
ind = FooInd()
self.foo(copy.deepcopy(ind))
if __name__ == "__main__":
p = Planning()
p.main()
Output:
1

How to use a variable that inside of a function of a class in another class - Python

I am trying to access to another variable that inside a function and also that is from another class, so I coded it in that way
class Helloworld:
def printHello(self):
self.hello = 'Hello World'
print (self.hello)
class Helloworld2(Helloworld):
def printHello2(self)
print(self.hello)
b = Helloworld2()
b.printHello2()
a = Helloworld()
a.printHello()
However, this gives me that error: AttributeError: 'Helloworld2' object has no attribute 'hello'. So, what would be the simplest way to access to that variable?
That's because you never call printHello(self) that declare your self.hello.
To make it work you need to do:
class Helloworld2(Helloworld):
def printHello2(self):
super().printHello()
print(self.hello)
Or move declaration of you self.hello to __init__() which would be more preferred way.
You should initialise the instance of the class via the __init__() function, this means that when it is created, these values are set.
That would make your code look like:
class Helloworld:
def __init__(self):
#sets self.hello on creation of object
self.hello = 'Hello World'
def printHello(self):
print (self.hello)
class Helloworld2(Helloworld):
def printHello2(self):
print(self.hello)
b = Helloworld2()
b.printHello2()
a = Helloworld()
a.printHello()
An alternative, with your current code is to just call printHello(), either at the top level, with b.printHello(), or within printHello2. Note that in this case, you don't actually need to use super().printHello() as you are not re-defining that function in Helloworld2, though it would be required if you did.

python name mangling in __init__ seems inconsistent

I'm trying to use a subclass that enhances instead of overriding the base class. I'm using the super method to call the base class. I find that I need to use the name mangling feature in __init__ (but only in init?) to make the code work. So for the heck of it I made the this print example. Since I didn't use name mangling I expected it to call subclass twice when I did the init, instead it calls the base class
It seems that __init__ sometimes sees the base class and sometimes sees the subclass. I'm sure it's just an incomplete understanding on my part, but was do I need name mangling for the real code, when in the print example it calls the base and subclass just fine?
the code
class base:
def __init__(self):
self.print()
def print(self):
print("base")
class subclass(base):
def __init__(self):
super(subclass, self).__init__()
self.print()
def print(self):
super(subclass, self).print()
print("subclass")
x = base()
x.print()
print("--")
y = subclass()
y.print()
the output - why doesn't y = subclass() print subclass instead of base since I didn't use name mangling?
> ./y.py
base
base
--
base
subclass
base
subclass
base
subclass
broken code when I don't use name mangling, works when I use self.__set and __set = set (the commented code). It gets the following error when I don't use __set:
File "./x.py", line 5, in __init__
self.set(arg)
TypeError: set() missing 1 required positional argument: 'arg2'
the code:
class base:
def __init__(self, arg):
self.set(arg)
# self.__set(arg)
# __set = set
def set(self, arg):
self.arg = arg
def print(self):
print("base",self.arg)
class subclass(base):
def __init__(self, arg1, arg2):
super(subclass, self).__init__(arg1)
self.set(arg1, arg2)
def set(self, arg1, arg2):
super(subclass, self).set(arg1)
self.arg2 = arg2
def print(self):
super(subclass, self).print()
print("subclass", self.arg2, self.arg)
x = base(1)
x.print()
x.set(11)
x.print()
y = subclass(2,3)
y.print()
y.set(4,5)
y.print()
======= update =======
I rewrote the code to look like this:
class base:
def __init__(self):
print("base init")
self.print()
def print(self):
print("base print")
class subclass(base):
def __init__(self):
print("sc init")
super(subclass, self).__init__()
print("sc after super")
self.print()
def print(self):
print("subclass print start")
super(subclass, self).print()
print("subclass print")
y = subclass()
print("--")
y.print()
when I run I get this output:
sc init
base init
subclass print start <<<< why is the subclass print called here
base print
subclass print
sc after super
subclass print start
base print
subclass print
--
subclass print start
base print
subclass print
why does the self.print in the base init call the subclass print when I'm initing the subclass? I was expecting that to call the base print. it does call the base print when I call it outside of the init.
Your subclass print explicitly calls the superclass one. So every time subclass.print is called, both "base" and "subclass" will be printed. This happens three times, because you call the print method three times: in subclass.__init__, in base.__init__ (which is called by subclass.__init__), and in subclass.print (which calls the superclass version).
In your "set" example, subclass.__init__ calls base.__init__, which tries to call self.set with just one argument. But since you are instantiating subclass, self.set is subclass.set, which takes two arguments.
It's unclear what you're trying to achieve with these examples. Your subclass doesn't really need to call base.__init__, because all that would do is call base.set, and you're already calling that from subclass.set. So even if you succeeded with all your calls, it would result in some methods getting called multiple times, just like with the print example.
My impression is that you're getting a bit carried away and trying to have every method call its superclass version. That's not always a good idea. If you write a subclass, and it calls a superclass method, you need to make sure that the subclass still provides an interface that's compatible with what the superclass expects. If it doesn't, you may need to not call the superclass method and instead have the subclass incorporate its functionality "inline" (although this may be more risky if other classes out in the world have made assumptions about how the base class works). The upshot is that you always need to think about what methods call which others; you can't just call every superclass method everywhere and expect that to work.

Dictionary of functions for all function in class

I'm relatively new to python and I have a class that has a bunch of different function. I read in the user input and depending on the user input I call a different function. Instead of having a bunch of if else statements I thought it would be better to have a dictionary of functions so currently my class looks like this:
class Foo:
def func1(self):
#do something
def func2(self, arg1):
#do something else
def func3(self, arg1, arg2):
#do something
def func4(self, arg1):
#do something
def __init__(self):
self.functions = {"FUNC2": func2, "FUNC4":func4}
def run_loop(self):
while 1:
user_input = raw_input()
cmd = user_input.split(' ')[0]
if cmd in self.functions:
self.functions[cmd].__get__(self, type(self))()
else:
#call other functions
I'm calling this in a main.py like so:
c = Class()
c.run_loop()
My issue is that I'm getting the following error NameError: global name 'func2' is not defined`. I'm not really sure why this is happening. I get the error in the constructor. Any ideas?
You need to specify that the function is within the class by adding self before it.
def __init__(self):
self.functions = {"FUNC2": self.func2, "FUNC4":self.func4}
You need to use self to access class functions from other function in same class. The corrected code will be
self.functions = {"FUNC2": self.func2, "FUNC4":self.func4}
The function is not identified within the class. Function "func2" & "func4" are part of the class and can be referred using the self...

TypeError: worker() takes 0 positional arguments but 1 was given [duplicate]

This question already has answers here:
"TypeError: method() takes 1 positional argument but 2 were given" but I only passed one
(10 answers)
Closed 8 months ago.
I'm trying to implement a subclass and it throws the error:
TypeError: worker() takes 0 positional arguments but 1 was given
class KeyStatisticCollection(DataDownloadUtilities.DataDownloadCollection):
def GenerateAddressStrings(self):
pass
def worker():
pass
def DownloadProc(self):
pass
Your worker method needs 'self' as a parameter, since it is a class method and not a function. Adding that should make it work fine.
If the method doesn't require self as an argument, you can use the #staticmethod decorator to avoid the error:
class KeyStatisticCollection(DataDownloadUtilities.DataDownloadCollection):
def GenerateAddressStrings(self):
pass
#staticmethod
def worker():
pass
def DownloadProc(self):
pass
See https://docs.python.org/3/library/functions.html#staticmethod
You forgot to add self as a parameter to the function worker() in the class KeyStatisticCollection.
This can be confusing especially when you are not passing any argument to the method. So what gives?
When you call a method on a class (such as work() in this case), Python automatically passes self as the first argument.
Lets read that one more time:
When you call a method on a class (such as work() in this case), Python automatically passes self as the first argument
So here Python is saying, hey I can see that work() takes 0 positional arguments (because you have nothing inside the parenthesis) but you know that the self argument is still being passed automatically when the method is called. So you better fix this and put that self keyword back in.
Adding self should resolve the problem. work(self)
class KeyStatisticCollection(DataDownloadUtilities.DataDownloadCollection):
def GenerateAddressStrings(self):
pass
def worker(self):
pass
def DownloadProc(self):
pass
class KeyStatisticCollection(DataDownloadUtilities.DataDownloadCollection):
def GenerateAddressStrings(self):
pass
def worker(self):
pass
def DownloadProc(self):
pass
I get this error whenever I mistakenly create a Python class using def instead of class:
def Foo():
def __init__(self, x):
self.x = x
# python thinks we're calling a function Foo which takes 0 args
a = Foo(x)
TypeError: Foo() takes 0 positional arguments but 1 was given
Oops!
Check if from method with name method_a() you call method with the same name method_a(with_params) causing recursion
just pass self keyword in def worker(): function
class KeyStatisticCollection(DataDownloadUtilities.DataDownloadCollection):
def GenerateAddressStrings(self):
pass
def worker(self):
pass
def DownloadProc(self):
pass
another use case for this error is when you import functions within the class definition. this makes the subsequent function calls a part of the class object. In this case you can use #staticmethod on the library import function or make a static path call directly to the function. see example below
In this example "self.bar()" will throw a TypeError, but it can be fixed in two ways
# in lib.py
def bar():
print('something to do')
# in foo.py
class foo():
from .lib import bar
def __init__(self):
self.bar()
Option 1:
# in lib.py
def bar():
print('something to do')
# in foo.py
class foo():
from .lib import bar
def __init__(self):
lib.bar()
Option 2:
# in lib.py:
#staticmethod
def bar():
print('something to do')
# in foo.py
class foo():
from .lib import bar
def __init__(self):
self.bar()
When doing Flask Basic auth I got this error and then I realized I had wrapped_view(**kwargs) and it worked after changing it to wrapped_view(*args, **kwargs).
class KeyStatisticCollection():
def GenerateAddressStrings(self):
pass
def worker():
return blabla
def DownloadProc(self):
abc = self.GenerateAddressStrings()
#abc = GenerateAddressStrings()#error
blabla = worker()
#blabla = self.worker()#error
i think this is a better explaination about using self param

Categories

Resources