TypeError: 'list' object is not callable, error calling extend from inherited list class - python

I wrote the following code,
#sanitize fuction
def sanitize(time_string):
if '-' in time_string:
splitter = '-'
elif ':' in time_string:
splitter = ':'
else:
return(time_string)
(mins, secs) = time_string.split(splitter)
return(mins + '.' + secs)
class AthleteList(list):
def __init__(self, a_name, a_dob=None, a_times=[]):
list.__init__([])
self.name = a_name
self.dob = a_dob
self.extend = a_times
def top3(self):
return(sorted(set([sanitize(t) for t in self]))[0:3])
#get coach data fuction
def get_coach_data(filename):
try:
with open(filename) as f:
data = f.readline()
templ = data.strip().split(',')
return(AthleteList(templ.pop(0), templ.pop(0), templ))
except IOError as ioerr:
print('File error: ' + str(ioerr))
return(None)
sarah = get_coach_data("sarah2.txt")
julie = get_coach_data("julie2.txt")
james = get_coach_data("james2.txt")
mikey= get_coach_data("mikey2.txt")
vera = AthleteList('vera')
vera.append('1.33')
vera.extend(['1.74','1.46','1.42','1.40'])
print(vera.top3())
When I run this code, it shows the following error.
But it only shows error when I use extend method.
I can use append method with no probs.
vera.extend(['1.74','1.46','1.42','1.40'])
TypeError: 'list' object is not callable

Follow the execution path from AthleteList('vera'), noting how self.extend gets initialized to a list, which shadows the function you expect.
what's happening is essentially this:
>>> extend = []
>>> extend(['foo'])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'list' object is not callable

To Access list you need to use the square brackets ([]) and not the parenthesis (()).
instead of
vera.extend(['1.74','1.46','1.42','1.40'])
use
aList = ['1.74','1.46','1.42','1.40']
vera.extend(aList)

You're basically trying to call a list (self.extend = a_times and a_times = []), which is impossible.
What you'd need to do, is use:
vera.extend.extend(['1.74','1.46','1.42','1.40'])
Or either this (as mentioned before):
vera.extend = ['1.74','1.46','1.42','1.40']
But actually this is not exactly correct either (given we need vera list and not vera.extend one [missed this when first posted, sorry!]), as shown here:
>>> vera = AthleteList("vera")
>>> vera.extend = ['1.74','1.46','1.42','1.40']
>>> print(vera.top3())
[]
>>> vera.extend.extend(['1.74','1.46','1.42','1.40'])
>>> print(vera.top3())
[]
The correct answer would be remove self.extend from AthleteList class so it works the way you want it (vera.extend(['1.74','1.46','1.42','1.40'])).
>>> vera = AthleteList("vera")
>>> vera.extend(['1.74','1.46','1.42','1.40'])
>>> print(vera.top3())
['1.40', '1.42', '1.46']
So, class should be like this:
class AthleteList(list):
def __init__(self, a_name, a_dob=None, a_times=[]):
list.__init__([])
self.name = a_name
self.dob = a_dob
def top3(self):
return(sorted(set([sanitize(t) for t in self]))[0:3])
Hope it helps!

According to your code, you have initialized a class variable extend to an empt list.
self.extend = a_times
where a_times = []
It is a variable, not a function according to your code. That is why it is throwing an error of 'not callable'
Change the following line of code:
vera.extend(['1.74','1.46','1.42','1.40']) to vera.extend = ['1.74','1.46','1.42','1.40'].
Hope it helps!

I think the problem is in the definition of class AtheleteList
self.extend = a_times should be change to self.extend(a_times)

Related

TypeError: 'str' object is not callable Python 3.6.1

I create python Project and make a class with some methods and property (variable) when I run my script the Python Interpretation tell me:
Traceback (most recent call last):
child.class#gmail.com
File "C:/.../Python_Tutorials/Object_Orinted_Programming.py", line 272, in
Child_Instance.name("child")
TypeError: 'str' object is not callable
it is the Code:
class Mother_Class:
def __init__(self,parm1,parm2):
self.name = (parm1)
self.family = (parm2)
self.full_name = (self.name + " " + self.family)
self.email = (self.name+"."+self.family+"#gmail.com")
def full_name(self,parm1,parm2):
print ("Your Full Name is: "+parm1 + "" + parm2)
class Child_Class(Mother_Class):
def name(self,name):
name = ( name )
def family(self,family):
family = ( family )
def Some_Methods(self):
print ("Some information is Here: ")
Instance = Mother_Class("mother","class")
print (Instance.full_name)
print (Instance.email)
print ("")
Child_Instance = Child_Class("child","class")
Child_Instance.name("overwriteclass")
print (Child_Instance.full_name)
What are the Problems?
The following method rewrites the method name with the value passed to the function.
def name(self,name):
name = ( name )
So, when you then try to call the "method", you're actually trying to call the string that you overwrote the method with.
Fixing is going to require a structural change of some sort because you are trying to use name as both a method name and a property name. Maybe:
def set_name(self, name):
self.name = name

TypeError: 'dict' object is not callable from main

I wrote a code which is going to store occurrences of words from a text file and store it to a dictionary:
class callDict(object):
def __init__(self):
self.invertedIndex = {}
then I write a method
def invertedIndex(self):
print self.invertedIndex.items()
and here is how I am calling:
if __name__ == "__main__":
c = callDict()
c.invertedIndex()
But it gives me the error:
Traceback (most recent call last):
File "E\Project\xyz.py", line 56, in <module>
c.invertedIndex()
TypeError: 'dict' object is not callable
How can I resolve this?
You are defining a method and an instance variable in your code, both with the same name. This will result in a name clash and hence the error.
Change the name of one or the other to resolve this.
So for example, this code should work for you:
class CallDict(object):
def __init__(self):
self.inverted_index = {}
def get_inverted_index_items(self):
print self.inverted_index.items()
And check it using:
>>> c = CallDict()
>>> c.get_inverted_index_items()
[]
Also check out ozgur's answer for doing this using #property decorator.
In addition to mu's answer,
#property
def invertedIndexItems(self):
print self.invertedIndex.items()
then here is how you'll cal it:
if __name__ == "__main__":
c = callDict()
print c.invertedIndexItems
Methods are attributes in Python, so you can't share the same name between them. Rename one of them.

Dot operator acting weird

I am new to python app development. When I tried a code I'm not able to see its output. My sample code is:
class name:
def __init__(self):
x = ''
y = ''
print x,y
When i called the above function like
some = name()
some.x = 'yeah'
some.x.y = 'hell'
When i called some.x it works fine but when i called some.x.y = 'hell' it shows error like
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
some.x.y = 'hell'
AttributeError: 'str' object has no attribute 'y'
Hope you guys can help me out.
First of all, you are defining the class with the wrong way, you should;
class name:
def __init__(self):
self.x = ''
self.y = ''
print x,y
Then, you are calling the wrong way, you should;
some = name()
some.x = 'yeah'
some.y = 'hell'
The problem is, x and y are strings. If you want to some.x.y for some reason, you should define x on your own.In other words, you can't use some.x.y for now.
Ok, you still need for some.x.y;
class name:
def __init__(self):
pass
some = name()
some.x = name()
some.x.y = "foo"
print some.x.y
>>> foo
x and y are two different variables on your instance some.
When you call some.x, you are returning the string 'yeah'. And then you call .y, you are actually trying to do 'yeah'.y, which is why it says string object has no attribute y.
So what you want to do is:
some = name()
some.x = 'hell'
some.y = 'yeah'
print some.x, some.y
When you perform some.x you are no longer dealing with the some, you are dealing with the type that some.x is. Since 'foo'.y doesn't make sense, you cannot do it with some.x either since it is of the same type as 'foo'.
These are different variables. So when you do chain .y onto some.x you are looking for a member variable y of a string which does not exist
some = name()
some.x = 'yeah'
some.y = 'hell'
if you want to make a single string out of both x and y you can use + to concatenate them together as follows
s = some.x + ' ' + some.y
print s # prints out "yeah hell"
class name:
def __init__(self):
x = ''
y = ''
def ___str__(self):
print x + ' ' y
now you can print the class and get
print some # prints "yeah hell"

AttributeError: 'list' object has no attribute 'display' in python

Error comes when i call the display function using class object
What should i do to overcome this ??
class A:
def __init__(self, fname, lname, age):
self.fname = fname
self.lname = lname
self.age = age
def disply(self):
fp = open("abc","r")
for lines in fp:
temp = lines.split(", ")[-1]
fp.close()
print a
a = [A("Taylor","Launter",22), A("James","bond",40)]
a.display()
You have a list of instances called a. a isn't the instance/s, it's a list.
You probably meant to do:
for myobject in a:
myobject.disply() # Note "disply" instead of "display"
a = [A("Taylor","Launter",22), A("James","bond",40)]
a.display()
Now a is a list. Lists in python dont have display method.
What you might actually have wanted to do is to invoke display method of the object of A. If that is the case, you might want to do something like this
for currentObject in [A("Taylor","Launter",22), A("James","bond",40)]:
currentObject.display()
Edit Your display method doesnt make any sense to me.

Error accessing class objects in python

I am having some problem accessing class instances. I am calling the class from a procedure, name of instance is defined in some variable. I want the instance name to be created of that value and then want to access it, but when i access it is giving error. Can some one please help to resolve this issue.
class myclass:
def __init__(self,object):
self.name = object
def mydef():
global a1
b = "a1"
b = myclass(b)
mydef()
print a1.name
Second Problem:
In my actual script, I have to create a large number of such instances from this function (around 100). So defining their name as global would be painful, is there a way i could access those instances outside function without having to declare them as global.
Modification:
class myclass:
def __init__(self,object,typename):
self.name = object
self.typeid = typename
def mydef():
file_han = open(file,"r")
while True:
line = file_han.readline()
if not line:
break
start = line.find('"')
end = line.find('"',start+1)
string_f = line[start+1:end]
myclass(string_f,'a11')
mydef(file)
print def.name
print def.typeid
File Contents are :
a11 "def"
a11 "ghi"
a11 "eff"
Here's how I'd do it. I don't know why you're messing around with globals, if you'd care to explain, I'll update my answer.
class Myclass(object):
def __init__(self, name):
self.name = name
def mydef():
return Myclass("a1")
a1 = mydef()
print a1.name
Gather your instances in a list:
instances = []
for x in range(1000):
instances.append(Myclass("Instance {0}".format(x)))
print instance[42].name
Note the changes:
Class names should be capitalized
Use object as the base class of your classes (since python 2.2, but no longer necessary in 3.x)
Don't shadow the built-in object with your parameter name
Just use the string "a1" directly as a parameter instead of assigning it to a variable
Return something from the function instead of passing the result by global variable
RE: Comment
You haven't said anything about the format of these files, so I'll just give an example where the file to be read contains one class name per line, and nothing else:
def mydef(filename):
ret = []
with open(filename) as f:
for line in f:
# Call `strip` on line to remove newline and surrounding whitespace
ret.append(Myclass(line.strip()))
return ret
So if you have several files and wish to add all your instances from all your files to a large list, do it like this:
instances = []
for filename in ["myfile1", "myfile2", "myfile3"]:
instances.extend(mydef(filename))
RE: OP Edit
def mydef(filename):
ret = []
with open(filename, "r") as file_han:
for line in file_han:
string_f = line.split('"')[1]
ret.append(Myclass(string_f))
return ret
i = mydef("name_of_file")
RE: Comment
Oh, you want to access them by name. Then return a dict instead:
def mydef(filename):
ret = {}
with open(filename, "r") as file_han:
for line in file_han:
string_f = line.split('"')[1]
ret[string_f] = Myclass(string_f)
return ret
i = mydef("name_of_file")
print i["ghi"].name # should print "ghi"
RE: Comment
If I understand you correctly, you want to have it both ways -- index by both line number and name. Well then why don't you return both a list and a dictionary?
def mydef(filename):
d = {}
L = []
with open(filename, "r") as file_han:
for line in file_han:
string_f = line.split('"')[1]
instance = Myclass(string_f)
d[string_f] = instance
L.append(instance)
return L, d
L, d = mydef("name_of_file")
print d["ghi"].name
print L[3]
print L.index(d["ghi"])
You could use class as repository for your instances, for example
class Named(object):
def __init__(self,name):
self.name = name
def __new__(cls,name):
instance = super(type,cls).__new__(cls,name)
setattr(cls,name,instance)
return instance
def __repr__(self):
return 'Named[%s]'%self.name
Named('hello')
Named('x123')
Named('this is not valid attribute name, but also working')
print(Named.hello,Named.x123,getattr(Named,'this is not valid attribute name, but also working'))

Categories

Resources