Passing class objects to another class method Python - 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

Related

How to import function into a class from external file?

I am coding a simple game of tic-tac-toe. My function to check winning is too repetitive and big, so I want to put it into an external file. My idea is:
class Game(object):
def __init__(self):
pass
import funcFile
instance = Game()
instance.func()
While in funcFile.py is:
def func():
print("Hello world!")
But:
Traceback (most recent call last):
instance.func()
TypeError: 'module' object is not callable
Is there a way to do this, or should I put everything in one file?
There are many ways to solve this kind of problem.
The most straightforward solution (which is what I think you had in mind) is to factor out the implementation of the func method to a separate module. But you still need to define the method in the class.
main.py:
from func_module import func_implementation
class Game: # note: you don't need (object)
def __init__(self):
pass
def func(self):
return func_implementation()
instance = Game()
instance.func()
func_module.py:
def func_implementation():
print('hello')
Another approach would be to factor out the func method to another class which the Game class inherits. This pattern is also known as a mixin class:
main.py:
from func_module import FuncMixin
class Game(FuncMixin):
def __init__(self):
pass
instance = Game()
instance.func()
func_module.py:
class FuncMixin:
def func(self):
print('hello')
But this is less clear, as you can't immediately see that the Game class has a func method and what it does. Also you can introduce subtle bugs with multiple inheritance if you're not careful. So in your case I'd prefer the first approach.
You should try from funcFile import func in your main file:
from funcFile import func
class Game(object):
def __init__(self):
pass
import funcFile
instance = Game()
instance.func()

class declaration in exec inits class, but functions don't work

I am going to attach two blocks of code, the first is the main code that is ran the second is the testClass file containing a sample class for testing purposes. To understand what's going on it's probably easiest to run the code on your own. When I call sC.cls.print2() it says that the self parameter is unfulfilled. Normally when working with classes, self (in this case) would be sC.cls and you wouldn't have to pass it as a parameter. Any advice is greatly appreciated on why this is occuring, I think it's something to do with exec's scope but even if I run this function in exec it gives the same error and I can't figure out a way around it. If you'd like any more info please just ask!
import testClass
def main():
inst = testClass.myClass()
classInfo = str(type(inst)).split()[1].split("'")[1].split('.')
print(classInfo)
class StoreClass:
def __init__(self):
pass
exec('from {} import {}'.format(classInfo[0], classInfo[1]))
sC = StoreClass()
exec('sC.cls = {}'.format(classInfo[1]))
print(sC.cls)
sC.cls.print2()
if __name__ == '__main__':
main()
class myClass:
def printSomething(self):
print('hello')
def print2(self):
print('hi')

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.

How to initialize several methods inside a python object

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__

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