This question already has answers here:
TypeError: worker() takes 0 positional arguments but 1 was given [duplicate]
(11 answers)
Closed 4 years ago.
In testing multiple inheritance, I have the follow Date, Time and DateTime class heirarchy
class time:
def __init__(self, time):
self.time = time
def getTime():
return self.time;
class date:
def __init__(self, date):
self.date = date
def getDate():
return self.date
class datetime(time,date):
def __init__(self, input_time, input_date):
time.__init__(self, input_time)
date.__init__(self, input_date)
Instantiating and checking the date works fine:
my_datetime = datetime("12PM","Today")
my_datetime.date
'Today'
But running the getDate function yeilds a parameter error and I don't understand why
my_datetime.getDate()
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-17-120ecf58a608> in <module>
----> 1 my_datetime.getDate()
TypeError: getDate() takes 0 positional arguments but 1 was given
Your issue has nothing to do with the multiple inheritance issue. In fact, you'd get exactly the same error trying to call getDate on an instance of date.
The cause of the issue is that you've forgotten to list self as an argument to getDate (and time.getTime as well). The instance the method gets called on will be passed automatically as the first positional argument, so you need to write the method with that in mind.
The error is telling you what is wrong. You've defined getDate to accept no parameters. When you do someObject.someMethod(), python automatically passes the object instance as the first parameter (almost universally named self).
If getDate should be called on an instance of the class, you need to define it like this:
def getDate(self):
...
Related
I'm writing a code to simplify a graph. In this case I've needed to remove a node of degree 2 and connect its two neighbors each other. Here is the simplified code
class node():
def __init__(self,ind):
#some code
self.neighbors=queue() #queue is another class defined by me
self.distances=queue()
#some code
def addngh(self,nd,distance):
#some code
def remngh(self,nd): #remove node "nd" from neighbors queue
#some code
def d2noderem(self): #removing self node from its left,right neighbors' "neighbors" queue by passing self to left and right's "remngh" function
left,right = self.neighbors[0:2]
#some code
left.remngh(self) #======= Error occurs at here ==========
right.remngh(self)
#some code
when I call that d2noderem function the following error occurs
File "/path/to/file/simplifygraphs.py", line 51, in d2noderem left.remngh(self)
TypeError: remngh() missing 1 required positional argument: 'nd'
Then I tried with
left.remngh(self,self)
and this is the result
File "/path/to/file/simplifygraphs.py", line 51, in d2noderem left.remngh(self,self)
TypeError: remngh() takes 2 positional arguments but 3 were given
I can't understand how did the no of args increased from 0 to 3 by adding 1 more argument.
And I couldn't find a solution for this problem yet.
How to overcome this type of problem?
I appreciate your help very much
The method 'remng' expects an argument as defined by the parameter 'nd' in def remngh(self,nd): Since you're calling it without supplying the expected argument, it's throwing an error.
You should either provide the expected argument or rewrite the function entirely.
I have this three functions inside a class below
def metrics(self,*args):
portfolio_return=np.sum(self.returns.mean()*self.weights)*252
portfolio_volatility=np.sqrt(np.dot(self.weights.T,np.dot(self.returns.cov()*252,self.weights)))
return np.array([portfolio_return,portfolio_volatility,portfolio_return/portfolio_volatility])
def objective(self):
return -self.metrics()[2]
def optimize(self):
optimum=optimization.minimize(fun=self.objective,x0=self.weights,args=self.returns,method='SLSQP',
bounds=self.bounds,constraints=self.constraints)
self.optimum = optimum
return self.optimum
This throws a
TypeError: objective() takes 1 positional argument but 3 were given
I tried adding *args as argument to objective. The code runs, but unfortunately it wasn't able to get the best parameters.
I wrote a decorated along these lines:
from functools import wraps
def mark_something(f):
#wraps(f)
def decorated(*args, **kwargs):
# How do I find the pd.DataFrame parameter of the decorated function?
# df = args[<pos_1>] or kwargs['df']
df = df.apply(lambda x: ...)
return f(*args, **kwargs)
return decorated
The wrapped method receives a DatFrame parameter as the 2nd parameter.
The problem is that the caller can do either foo(something, my_df) and then I need to look in args or foo(something, df=my_df) and I need to look in kwargs.
Is there a "nice" way to find a parameter in the wrapped function without having to explicitly check both dictionary and list?
EDIT
I tried kwargs.get('df', args[1]) but that throws an error since args has a single item ... I thought that optional part is evaluated only if get fails ...
Since your decorator is very specific, ie it has a dataframe and a single non-keyword argument, you could use the correct argument signature in your decorator method.
def wrapper(fun):
def working(a, kwd=None):
print("arg: ", a)
print("kwarg: ", kwd)
return fun(a, kwd)
return working
#wrapper
def testme(a, kwd=None):
print("running: ", a, kwd)
testme(1, 2)
testme(1, kwd=3)
The output is then:
arg: 1
kwarg: 2
running: 1 2
arg: 1
kwarg: 3
running: 1 3
Of course this could be improved by add #wraps from functools, but I think the idea is there.
I have been working with classes however when ever I try to call an object within a class, I keep getting a message saying that the call takes no arguments. A simple example is in the following where I try to call a card, however it will not show. Do you have any idea as to what can be causing the issue?
class Card(object):
def _init_(self, symbol, rank):
self.symbol = symbol
self.rank = rank
def show(self):
print("{} of {}".format(self.rank, self.symbol))
card = Card("clubs", 6)
card.show(self)
The following is the error that appears:
card = Card("clubs", 6)
TypeError: Card() takes no arguments
You need to name the constructor method __init__, with two underscores on either side, not _init_.
As answered by #jwodder, you have to use __init__. Also while calling the show() you should call card.show().
I have a class that is called in a couple of contexts:
class Datamodel:
def __init__(self, habvalues, hablist=[], orglist=[], genlist=[]):
self.habvalues = habvalues
self.uses_database = False
if hablist and orglist and genlist:
self.hablist = hablist
self.orglist = orglist
self.genlist = genlist
self.uses_database = True
There is one method that calls this class using only the habvalues parameter, and it seems to work fine. However, when called using all the parameters, with lists that are shown by my logging calls to contain valid data, I get the following error message:
__ init__() takes 7 positional arguments but 8 were given
The calling function reads like this:
self.newmodel = evocontrol.Datamodel(self.habvalues, self.habRecords, self.orgRecords, self.genlist)
So, the error message seems to be wrong. There are not 7 positional arguments in my code, only 4. And only 4 are given.
What could be the source of a miscount such as this? What kinds of things should I be looking for here?
Please, try passing the arguments as keyword arguments
self.newmodel = evocontrol.Datamodel(self.habvalues, hablist=self.habRecords, orglist=self.orgRecords, genlist=self.genlist)