For the error:
TypeError: takes exactly 1 argument (2 given)
With the following class method:
def extractAll(tag):
...
and calling it:
e.extractAll("th")
The error seems very odd when I'm giving it 1 argument, the method should take only 1 argument, but it's saying I'm not giving it 1 argument....I know the problem can be fixed by adding self into the method prototype but I wanted to know the reasoning behind the error.
Am I getting it because the act of calling it via e.extractAll("th") also passes in self as an argument? And if so, by removing the self in the call, would I be making it some kind of class method that can be called like Extractor.extractAll("th")?
The call
e.extractAll("th")
for a regular method extractAll() is indeed equivalent to
Extractor.extractAll(e, "th")
These two calls are treated the same in all regards, including the error messages you get.
If you don't need to pass the instance to a method, you can use a staticmethod:
#staticmethod
def extractAll(tag):
...
which can be called as e.extractAll("th"). But I wonder why this is a method on a class at all if you don't need to access any instance.
If a non-static method is member of a class, you have to define it like that:
def Method(self, atributes..)
So, I suppose your 'e' is instance of some class with implemented method that tries to execute and has too much arguments.
Am I getting it because the act of calling it via e.extractAll("th") also passes in self as an argument?
Yes, that's precisely it. If you like, the first parameter is the object name, e that you are calling it with.
And if so, by removing the self in the call, would I be making it some kind of class method that can be called like Extractor.extractAll("th")?
Not quite. A classmethod needs the #classmethod decorator, and that accepts the class as the first paramater (usually referenced as cls). The only sort of method that is given no automatic parameter at all is known as a staticmethod, and that again needs a decorator (unsurprisingly, it's #staticmethod). A classmethod is used when it's an operation that needs to refer to the class itself: perhaps instantiating objects of the class; a staticmethod is used when the code belongs in the class logically, but requires no access to class or instance.
But yes, both staticmethods and classmethods can be called by referencing the classname as you describe: Extractor.extractAll("th").
Yes, when you invoke e.extractAll(foo), Python munges that into extractAll(e, foo).
From http://docs.python.org/tutorial/classes.html
the special thing about methods is
that the object is passed as the first
argument of the function. In our
example, the call x.f() is exactly
equivalent to MyClass.f(x). In
general, calling a method with a list
of n arguments is equivalent to
calling the corresponding function
with an argument list that is created
by inserting the method’s object
before the first argument.
Emphasis added.
Summary (Some examples of how to define methods in classes in python)
#!/usr/bin/env python # (if running from bash)
class Class1(object):
def A(self, arg1):
print arg1
# this method requires an instance of Class1
# can access self.variable_name, and other methods in Class1
#classmethod
def B(cls, arg1):
cls.C(arg1)
# can access methods B and C in Class1
#staticmethod
def C(arg1):
print arg1
# can access methods B and C in Class1
# (i.e. via Class1.B(...) and Class1.C(...))
Example
my_obj=Class1()
my_obj.A("1")
# Class1.A("2") # TypeError: method A() must be called with Class1 instance
my_obj.B("3")
Class1.B("4")
my_obj.C("5")
Class1.C("6")`
try using:
def extractAll(self,tag):
attention to self
Related
Classes, methods, and instances have me thoroughly confused. Why is it that this works:
class Computer:
def config(self):
print('i5, 16gb, 1TB')
com1 = Computer()
com1.config()
But this does not?:
class Computer:
def config(self):
print('i5, 16gb, 1TB')
com1 = Computer()
Computer.config()
But, if you modify the code directly above to include the instance as an argument when calling the method, like so:
Computer.config(com1)
it works? I see the difference between the two, but I don't understand it.
In your example Computer.config is an instance method, means it is bound to an object, or in other words requires an object. Therefore in your second example you would write:
com1.config()
You can also write it in the following style:
Computer.config(com1)
which is the same and just syntactic sugar. In same special cases you might prefer the latter one, e.g. when duck typing is required, but the first one is definitely the preferred way.
In addition, there are staticmethod or classmethod functions, which don't require any objects. An example would be this:
class Computer
#staticmethod
def config():
print("Foo")
Computer.config() # no object required at all, because its a staticmethod
Please notice the missing self reference. Technically Computer.config as a staticmethod is just a simple function, but it helps to group functionalities so to make them a class member.
This is because config() is an instance method, and not a static method. An instance method, simply said, is shared across all objects of a class, and cannot be accessed by just using the class name. If you want to call config() by just using class name, you have to tell compiler that it is static. To do this use #staticmethod tag, and remove the self argument:
class Computer:
#staticmethod
def config():
print('i5, 16gb, 1TB')
com1 = Computer()
com1.config()
And as you said:
if you modify the code directly above to include the instance as an
argument when calling the method, like so:
This is because, every instance function takes self as it's first argument. Basically self is somewhat similar to this in C++ or Java, and it tells which object to work upon, i.e., self acts as a pointer to the current object. When you passed the com1 object to the argument, it took self for com1.
That means that when you invoke com1.config() what you are actually doing is calling config with com1 as its argument. So com1.config(() is the same as Computer.config(com1).
Why doesn't the second approach work?
Because Computer is an instance of something called a meta-class. It is somewhat the class definition and not actually an instance of Computer. com1 is an instance created by Computer. You can use com1 to invoke its non-static functions but you can't use the meta-class Computer to invoke non-static functions, which need an object to be ran on.
Why does the third approach work?
Have you noticed the self in the definition of the config function? That means that when you invoke com1.config() what you are actually doing is calling config with com1 as its argument. So com1.config() is the same as Computer.config(com1).
I am trying to create class that having one instance method, is it possible to create instance method without self.
class A():
def display():
print("Hi")
a = A()
a.display()
I am getting like this: Type Error: display() takes no arguments (1 given)
For an instance method, you need to add a parameter that represents the instance itself. It MUST be present and it MUST be the first parameter of the method - that's mandatory, you cannot change this. It can be called whatever you want, although self is the standard used by the community, which you should also follow.
class A():
def display(self):
print('Hi')
Now, as you probably noticed, we're not doing anything in particular with the instance in the display method. To avoid this redundancy, we need to use a different type of method.
A method which does not take an instance as an argument is called a static method and is represented by the #staticmethod decorator directy above the function definition:
class A():
#staticmethod
def display():
print('Hi')
Both snippets will run without errors and, producing the same output when you execute the following code:
a = A()
a.display()
But the second version is preferred - because explicit is better than implicit.
Using #staticmethod will work... but I won't recommend it for beginner uses
Usually function define an object behavior so you'll need the object itself using self !
As others have pointed out, an instance method must have at least one parameter, as the object itself is passed (implicitly) as the first argument. But why?
This def statement, like any other, defines a function, not a method. So where does the method come from? Let's go step by step.
class A:
def display(self):
print("Hi")
If we look directly in the dictionary that stores a class's attributes, we see that display is bound to an instance of function.
>>> type(A.__dict__['display'])
<class 'function'>
We get the same result if we try to access the attribute using the normal dot syntax:
>>> type(A.display)
<class 'function'>
But something ... different ... happens if we try to access that function via an instance of the class:
>>> type(A().display)
<class 'method'>
Where did the method come from? Anytime you access an attribute, the machinery that handles such access looks to see if the result has a __get__ method. The function type provides such a method, so instead of getting the function itself back, you get the result of calling that function's __get__ method. That is, A().display is really the same as A.display.__get__(A(), A). And what __get__ returns is an object that does two things:
Saves a reference to the instance A()
Saves a reference to the function A.display.
When you try to call this object, what it does is takes any arguments passed to it, and passes the saved reference to A() along with those arguments to the function A.display. That is,
a = A()
a.display() == A.display.__get__(a, A)(a)
An that's why display gets defined with one more argument than is seemingly necessary.
Others have also mentioned static methods. What does #staticmethod do? staticmethod is another type, whose instances wrap a function. The staticmethod definition of __get__, though, doesn't do anything other than return the underlying function, not any kind of new method object. So given
class A:
#staticmethod
def display():
print("Hi")
we can see that display is an instance of static method, not a function:
>>> >>> type(A.__dict__['display'])
<class 'staticmethod'>
and that the __get__ method returns the function itself, whether the attribute is accessed via the class
>>> type(A.display)
<class 'function'>
or an instance
>>> type(A().display)
<class 'function'>
In Python when we define class all its members including variables and methods also becomes attributes of that class. In following example MyClass1.a and MyClass1.mydef1 are attributes of class MyClass1.
class MyClass1:
a = 10
def mydef1(self):
return 0
ins1 = MyClass1() # create instance
print(MyClass1.a) # access class attribute which is class variable
print(MyClass1.mydef1) # No idea what to do with it so just printing
print(ins1.mydef1) # No idea what to do with it so just printing
Output
10
<function MyClass1.mydef1 at 0x0000000002122EA0>
<bound method MyClass1.mydef1 of <__main__.MyClass1 object at 0x000000000212D0F0>>
Here attribute a is a variable and it can be used like any other variable.
But mydef1 is a method, if it is not invoked and just used like MyClass1.mydef1 or ins1.mydef1, it returns object for that method(correct me if I am wrong).
So my question is, what can we do with the Class/instance methods without invoking it? Are there any use cases for it or is it just good to know thing?
An attribute of a class that happens to be a function becomes a method for instances or that class:
inst.foo(params, ...)
is internally translated into:
cls.foo(inst, params, ...)
That means that what is actually invoked is the attribute from the class of the instance, and the instance itself is prepended to the argument list. It is just Python syntax to invoke methods on objects.
In your example the correct uses would be:
print(MyClass1.mydef1(ins1)) # prints 0
print(ins1.mydef1()) # also prints 0
Well instance methods can be called with the appropriate parameters of course:
print(ins1.mydef1()) # no parameters, so empty parenthesis, this call should print "0" in your example instead of the method description
If you use it without the parenthesis, you are playing with reference to the function, I don't think you can have any use of it, except checking the list of methods available in a class or something like that.
I am trying to apply the timing decorator described here to a method within a class instead of a standalone method. How should this be done?
I am getting this error:
TypeError: unbound method wrapper() must be called with SomeClass instance as
first argument (got float instance instead)
EDIT
Thanks to your comment, I think I know what the problem is. This doesn't work:
class A:
#timings
#classmethod
def a(cls, x):
print(x)
A.a(2)
for exactly the reason you said.
TypeError: unbound method wrapper() must be called with A instance as first argument (got int instance instead)
But this does:
class A:
#classmethod
#timings
def a(cls, x):
print(x)
A.a(2)
So the order matters. I think what's going on here is that it's fooling the way python handles bound methods: When python looks at the member a, it has to make a decision:
Make a bound method
Make a class method
Do nothing (leave it as it is)
If it gets a regular function, it will do (1), and #timings produces a regular function.
Does this solve the problem?
I'm trying to get the name of all methods in my class.
When testing how the inspect module works, i extraced one of my methods by obj = MyClass.__dict__['mymethodname'].
But now inspect.ismethod(obj) returns False while inspect.isfunction(obj) returns True, and i don't understand why. Is there some strange way of marking methods as methods that i am not aware of? I thought it was just that it is defined in the class and takes self as its first argument.
You are seeing some effects of the behind-the-scenes machinery of Python.
When you write f = MyClass.__dict__['mymethodname'], you get the raw implementation of "mymethodname", which is a plain function. To call it, you need to pass in an additional parameter, class instance.
When you write f = MyClass.mymethodname (note the absence of parentheses after mymethodname), you get an unbound method of class MyClass, which is an instance of MethodType that wraps the raw function you obtained above. To call it, you need to pass in an additional parameter, class instance.
When you write f = MyClass().mymethodname (note that i've created an object of class MyClass before taking its method), you get a bound method of an instance of class MyClass. You do not need to pass an additional class instance to it, since it's already stored inside it.
To get wrapped method (bound or unbound) by its name given as a string, use getattr, as noted by gnibbler. For example:
unbound_mth = getattr(MyClass, "mymethodname")
or
bound_mth = getattr(an_instance_of_MyClass, "mymethodname")
Use the source
def ismethod(object):
"""Return true if the object is an instance method.
Instance method objects provide these attributes:
__doc__ documentation string
__name__ name with which this method was defined
__func__ function object containing implementation of method
__self__ instance to which this method is bound"""
return isinstance(object, types.MethodType)
The first argument being self is just by convention. By accessing the method by name from the class's dict, you are bypassing the binding, so it appears to be a function rather than a method
If you want to access the method by name use
getattr(MyClass, 'mymethodname')
Well, do you mean that obj.mymethod is a method (with implicitly passed self) while Klass.__dict__['mymethod'] is a function?
Basically Klass.__dict__['mymethod'] is the "raw" function, which can be turned to a method by something called descriptors. This means that every function on a class can be both a normal function and a method, depending on how you access them. This is how the class system works in Python and quite normal.
If you want methods, you can't go though __dict__ (which you never should anyways). To get all methods you should do inspect.getmembers(Klass_or_Instance, inspect.ismethod)
You can read the details here, the explanation about this is under "User-defined methods".
From a comment made on #THC4k's answer, it looks like the OP wants to discriminate between built-in methods and methods defined in pure Python code. User defined methods are of types.MethodType, but built-in methods are not.
You can get the various types like so:
import inspect
import types
is_user_defined_method = inspect.ismethod
def is_builtin_method(arg):
return isinstance(arg, (type(str.find), type('foo'.find)))
def is_user_or_builtin_method(arg):
MethodType = types.MethodType
return isinstance(arg, (type(str.find), type('foo'.find), MethodType))
class MyDict(dict):
def puddle(self): pass
for obj in (MyDict, MyDict()):
for test_func in (is_user_defined_method, is_builtin_method,
is_user_or_builtin_method):
print [attr
for attr in dir(obj)
if test_func(getattr(obj, attr)) and attr.startswith('p')]
which prints:
['puddle']
['pop', 'popitem']
['pop', 'popitem', 'puddle']
['puddle']
['pop', 'popitem']
['pop', 'popitem', 'puddle']
You could use dir to get the name of available methods/attributes/etc, then iterate through them to see which ones are methods. Like this:
[ mthd for mthd in dir(FooClass) if inspect.ismethod(myFooInstance.__getattribute__(mthd)) ]
I'm expecting there to be a cleaner solution, but this could be something you could use if nobody else comes up with one. I'd like if I didn't have to use an instance of the class to use getattribute.