I got the following python code where printSaved is called when a button is clicked (using the wx library and python 2.7.2). But when this happens i got a really strange error
Traceback (most recent call last):
File "./program.py", line 135, in printSaved
s = self.readSaved()
TypeError: readSaved() takes no arguments (1 given)
Here is the code
def readSaved():
f = codecs.open((os.getenv('HOME') +'/Dokument/savefile.txt') ,'r','utf-8')
l = f.readlines()
f.close()
return l
def printSaved(self,event):
s = self.readSaved()
for l in s:
print l
I fixed the problem by adding one argument to readSaved(somethingUseless) and everything worked fine. My question is what is passed to readSaved and HOW/WHY? Does this have something to do with the event?
In Python, the object on which a method is called is always passed in explicitly as an argument. This argument is conventionally called self.
The correct definition for readSaved() as an instance method should have this as the first line:
def readSaved(self):
# ...
If you want it to be a module-level function, you should call it as follows:
s = readSaved()
Methods are passed the instance as the first argument.
Is it defined within a class? I suppose it does, since the second method takes self.
If readSaved is an instance method, it takes self as first parameter as well. If you don't need it, use the #staticmethod decorator instead:
#staticmethod
def readSaved():
f = codecs.open((os.getenv('HOME') +'/Dokument/savefile.txt') ,'r','utf-8')
l = f.readlines()
f.close()
return l
As it is a method -- you're calling it as a method, anyway -- you have to have at least self as an argument. When a function is called as a method, the object you call the method through is passed as the first argument to that function.
Related
According to the following snippet:
import time
def custom_time():
return time.time()
class TimeWrapper:
builtin_time = time.time
def print_builtin(self):
print(self.builtin_time())
custom_time = custom_time
def print_custom(self):
print(self.custom_time())
wrapper = TimeWrapper()
wrapper.print_builtin()
# 1660163626.7973292
wrapper.print_custom()
# TypeError: custom_time() takes 0 positional arguments but 1 was given
time.time(wrapper)
# TypeError: time.time() takes no arguments (1 given)
custom_time(wrapper)
# TypeError: custom_time() takes 0 positional arguments but 1 was given
I do not understand why wrapper.print_builtin() is working.
Is it not supposed to be the equivalent of time.time(wrapper)?
Is there a connection with the unused argument from C implementation ?
If it is not the case, I'm still interested in this unused variable.
time.time has type builtin_function_or_method, not function. Such objects do not implement the descriptor protocol:
>>> time.time.__get__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'builtin_function_or_method' object has no attribute '__get__'
so self.builtin_time simply returns time.time, not a method object that implicitly passes self as the first argument to time.time.
That is, self.builtin_time() is exactly the same as time.time(), not time.time(self).
This is an interesting side-effect of how methods really work. A method is just a function in a class dictionary. For example:
class A:
def b(self):
print("b")
def c(self):
print("c")
A.c = c
a = A()
The reason that both b and c are equally methods of A is that they are descriptors. When you access a descriptor from an instance of a class using dot notation, as in a.b or a.c, python will perform the following binding: type(a).b.__get__(a). The bound method is a callable that automatically passes self to the underlying function. Whether you define a method in the class or outside a class and add it to the class dictionary by other means, it will behave the same.
The behavior of c in the example above is exactly the same as custom_time in your example. By setting custom_time = custom_time in the class body, you are creating a method just as if you had placed def custom_time(): in the class body. When you call the subsequently bound method as self.custom_time(), the bound method passes instance self as the first argument, even though the function accepts no arguments. Hence your error.
I'm writing a simple code snippet here, but unable to run the code
class test:
def __init__(self):
pass
def functiona(self, a):
b = a+0
print(b)
def functionb(self):
a = 5
self.functiona(a)
test.functionb('abc')
It errors out with "AttributeError: 'str' object has no attribute 'functiona'" Unable to call it with self. However, if I provide test.functiona(a) it works fine.
Few of other code samples works with self.function, how to solve this issue
test.functionb('abc') is a function call on the class, not on an instance.
I suppose it works if you do test().functionb('abc')?
The difference is:
In your case, you call the function object on the class. As it is not a staticmethod or classmethod, it is called with self = 'abc', a string. This string hasn't a method functiona().
In my case, the call operates on a class instance. Here, self is set to the instance you just created – and you get an error because it doesn't know where to pass the 'abc'.
Problem lies in the call test.functionb('abc'). You are not using object of the class to call the method. So, the self parameter is not passed.
Python considers, the first parameter to be self, and you passed 'abc' which is a string.
Use it like test().functionb('abc') , then the default first argument becomes the object of test - like functionb(test_ob, 'abc').
you can add the decorator #classmethod and then call it like you did
class test:
def __init__(self):
pass
#classmethod
def functiona(self, a):
b = a+0
print(b)
#classmethod
def functionb(self):
a = 5
self.functiona(a)
>>> test.functiona(1001)
>>> 1001
>>> test.functionb()
>>> 5
Problem lies in the call test.functionb('abc'). You are not using object of the class to call the method. So, the self parameter is not passed. Python considers, the first parameter to be self, and you passed 'abc' which is a string.
Use it like test().functionb('abc') , then the default first argument becomes the object of test - like functionb(test_ob, 'abc').
I am trying to pass dictionary to a function in python but it shows me error.
class stud:
def method(**arg):
print(arg)
dict1 = {1:"abc",2:"xyz"}
a = stud()
a.method(dict1)
This raises the following error:
>>> a.method(dict1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: method() takes 0 positional arguments but 2 were given
Can you tell me were I goes wrong or the right way to pass dictionary to a function?
As #Bit mentions, if method is not a static method. You need to add a self parameter.
There are two options here:
you use a normal parameter in the method:
class stud:
def method(self,arg): # normal parameter
print(arg)
you pass the dictionary as named parameters in the call:
class stud:
def method(self,**arg): # normal parameter
print(arg)
a.method(**dict1)
Personally I would go with the first one, since it is:
more efficient: you pass only a reference to the dictionary; and
if you want to alter the original dictionary, that is still possible.
I am completely new to python and I have experienced, for me, strange behaviour. I have two files: foo.py and test.py
test.py:
from foo import Foo
f = Foo()
f.bar(1)
When my foo.py looks as this:
class Foo:
def bar(n):
print n
I get error message:
Traceback (most recent call last):
File "test.py", line 3, in <module>
f.bar(1)
TypeError: bar() takes exactly 1 argument (2 given)
When my foo.py looks as this:
class Foo:
def bar(x,n):
print n
I get result:
1
Why is that? Why do I need to have two params declared, even though I want to have method which takes only one? Thank you
The first argument in a method is supposed to be the object on which the method is called. That is when you call f.foo(1) it means that foo will be called with the arguments foo(f, 1). Normally one calls the first argument for self, but python doesn't care about the name, your second example the object f will be sent via the x parameter.
The reason is because Python expects the first argument to be object which is calling the function. If you're familiar with C++ or Java, it's similar to the "this" keyword. Just that Python is more particular that you explicitly declare this rather than implicitly. The standard coding convention suggests that you use "self" as the first argument, but you could use any really.
In your example,
from foo import Foo
f = Foo()
f.bar(1)
When you call the function bar, which is inside the class Foo, it can be called as Foo.bar(f,n) or f.bar(n). Here, self is 'f' or referring to the current object calling the class.
I suggest having a look at Why explicit self has to stay for clearer understanding.
I'm a new Python programmer who is having a little trouble using 'self' in classes. For example:
class data:
def __init__(self):
self.table = []
def add(self, file):
self.table.append(file)
data.add('yes')
In this function I want to have table be a variable stored in the class data and use add to modify it. However, when I run this script it gives me the error:
Traceback (most recent call last):
File "/Projects/Python/sfdfs.py", line 7, in <module>
data.add('yes')
TypeError: add() takes exactly 2 positional arguments (1 given)
I assume that I am trying to call the function the wrong way in this instance, as this syntax is very similar to an example in the python documentation: http://docs.python.org/3.1/tutorial/classes.html
You first need to make an instance of the class:
mydata = data()
then you can call the method -- on the instance, of course, not on the class:
mydata.add('yes')
You need to instantiate the class before you can call methods on it:
mydata = Data()
mydata.add('yes')
you are calling the add method on the class object not an instance of the class.
It looks like what you want to do is:
classInst = data() #make an instance
classInst.add("stuff") #call the method
When add is invoked on an instance object, the instance object is passed as the self argument to the method. Having the self argument differentiates class methods from instance methods.
You are trying to call data.add() somewhat like you would call a static method in Java.
Try doing this instead:
d = data()
d.add('yes')
The self parameter tells the method that it operates on an object of type data.