Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 2 years ago.
Improve this question
Is hasattr() a method? It does take an object instance as a parameter, but it is not used as object.hasttr(). I would say it is not a method then?
Everything in Python is an object, even functions and methods. So the fact that hasattr() takes an object is nothing special, so do str() and input() and sum().
A method is a function that has been bound to an object by accessing it as an attribute; so "foo bar".split gives you the bound str.split method:
>>> "foo bar".split
<built-in method split of str object at 0x7f84bef6a730>
This one happens to be “built-in” because it is implemented as part of the Python runtime, but it’s no different from a function on a class written in Python.
Calling it returns the result of the method as applied to the string it is bound to:
>>> method = "foo bar".split
>>> method()
['foo', 'bar']
I can also use it directly, unbound:
>>> str.split("spam ham")
['spam', 'ham']
hasattr() is not bound. It's a function. You can't bind it like you could with Python functions even if your tried*.
Python functions, added to a class, become methods automatically when you access them as an attribute on an instance of the class:
>>> class KnightsWhoSayNi:
... pass
...
>>> def speak(self): return "Ni!"
...
>>> speak
<function speak at 0x10fe65f28>
>>> knight = KnightsWhoSayNi()
>>> hasattr(knight, "speak") # using that function you mentioned!
False
>>> KnightsWhoSayNi.speak = speak # adding the function to the class
>>> knight.speak # now it exists! As a method...
<bound method speak of <__main__.KnightsWhoSayNi object at 0x10fe71080>>
>>> knight.speak()
'Ni!'
Note how speak() was given an argument named self, but I didn't have to pass it in. Because the method is bound to a specific instance of the class, that's taken care of automatically. The first argument passed in is the instance. The name doesn't even matter, but self is the convention, best stick to that.
As an exercise, you could try the above example yourself. Then try adding hasattr to the class. You'll find that you cant use it like a method, it won't become bound via knight.hasattr`, the instance won't be passed in as the first argument, you will still have to pass in two arguments for it to work at all.
If you wanted to go off the deep end, you could learn about how binding works in the Python Descriptors HOW-TO. Don’t worry if that feels too big of a step, that’s quite advanced.
* To pre-empt not-picking: You can emulate binding by using functools.partial() or functools.partialmethod(), but that’s not quite the same thing.
Related
I can't seem to understand the difference between methods and functions.
From my knowledge I am aware that methods are functions that are unique to the classes they are implemented in, but for functions can I say that they can be used in general and are not restricted to a certain class. Also, is the indentation of functions vs methods another essential difference? As methods are implemented within classes and functions are outside with the least indentation.
A function is virtually the same as a method only that the latter is bound to a class. In Python, in most cases, the same way you define a function is the same way you define a method. However, to refer to the class it is in, you will at times see the 'self' parameter added to the method as in: def function_name(self):. The indentation works similarly in both cases.
I think the reason why you tend to think that the indentation of a method is deeper than that of a function is because by the time you're writing your method, you are already indented inside the class.
Python, in particular, across most programming languages, really does not differentiate much between functions and methods.
What you declare is true: "methods are functions that are unique to the classes they are implemented in" -
And that makes for the indentation difference: since methods are inside a class, they are indented inside the class statement block.
When you create a simple class, and retrieve a method from it directly, it is actually a function (in python 3 - it worked differently in old Python 2.x):
from types import FunctionType
class A:
def b(self):
pass
print(A.b, type(A.b) is FunctionType)
Prints:
<function A.b at 0x...> True
So, in Python, a "method" is really and literally a function!
It will work differently when retrieved from an instance of the class it is declared on.
[optional complicated paragraph] Then, Python wraps it with what can be described as "a lazy object callable that will insert the instance it is bound to as first argument to the underlying function when called." Once you can make sense of this phrase, you can check "seasoned Pythonista" in your CV.
What it means is simply that "self" will appear "magically" when calling the method, and moreover, one can go back to the original function by looking at the method's .__func__ attribute.
So, given the same class A above:
In [52]: print(A().b, type(A().b), type(A().b) is FunctionType)
<bound method A.b of <__main__.A object at 0x...>> <class 'method'> False
In [53]: print(A().b.__func__, type(A().b.__func__), type(A().b.__func__) is FunctionType)
<function A.b at 0x...> <class 'function'> True
Note that in these examples I instantiate a new object of the class A at each time, by writing A(), while in the first example, I retrieve b directly from the class, without parenthesis: A.b
As I stated in the beggining of the text: be aware that the fact a plain function can be used as a method is particular to Python, and both kinds of objects will likely have some differences in other programming languages. The idea however, will remain the same: a method will always "know" about the instance from where it was retrieved.
Consider the following code, I expected it to generate error. But it worked. mydef1(self) should only be invoked with instance of MyClass1 as an argument, but it is accepting MyClass1 as well as rather vague object as instance.
Can someone explain why mydef is accepting class name(MyClass1) and object as argument?
class MyClass1:
def mydef1(self):
return "Hello"
print(MyClass1.mydef1(MyClass1))
print(MyClass1.mydef1(object))
Output
Hello
Hello
There are several parts to the answer to your question because your question signals confusion about a few different aspects of Python.
First, type names are not special in Python. They're just another variable. You can even do something like object = 5 and cause all kinds of confusion.
Secondly, the self parameter is just that, a parameter. When you say MyClass1.mydef1 you're asking for the value of the variable with the name mydef1 inside the variable (that's a module, or class, or something else that defines the __getattr__ method) MyClass1. You get back a function that takes one argument.
If you had done this:
aVar = MyClass1()
aVar.mydef1(object)
it would've failed. When Python gets a method from an instance of a class, the instance's __getattr__ method has special magic to bind the first argument to the same object the method was retrieved from. It then returns the bound method, which now takes one less argument.
I would recommend fiddling around in the interpreter and type in your MyClass1 definition, then type in MyClass1.mydef1 and aVar = MyClass1(); aVar.mydef1 and observe the difference in the results.
If you come from a language like C++ or Java, this can all seem very confusing. But, it's actually a very regular and logical structure. Everything works the same way.
Also, as people have pointed out, names have no type associated with them. The type is associated with the object the name references. So any name can reference any kind of thing. This is also referred to as 'dynamic typing'. Python is dynamically typed in another way as well. You can actually mess around with the internal structure of something and change the type of an object as well. This is fairly deep magic, and I wouldn't suggest doing it until you know what you're doing. And even then you shouldn't do it as it will just confuse everybody else.
Python is dynamically typed, so it doesn't care what gets passed. It only cares that the single required parameter gets an argument as a value. Once inside the function, you never use self, so it doesn't matter what the argument was; you can't misuse what you don't use in the first place.
This question only arises because you are taking the uncommon action of running an instance method as an unbound method with an explicit argument, rather than invoking it on an instance of the class and letting the Python runtime system take care of passing that instance as the first argument to mydef1: MyClass().mydef1() == MyClass.mydef1(MyClass()).
Python is not a statically-typed language, so you can pass to any function any objects of any data types as long as you pass in the right number of parameters, and the self argument in a class method is no different from arguments in any other function.
There is no problem with that whatsoever - self is an object like any other and may be used in any context where object of its type/behavior would be welcome.
Python - Is it okay to pass self to an external function
I am reading a book about Object-Oriented Programming in Python. There is a sentence that I am confused by:
The interpreter automatically binds the instance upon which the method is invoked to the self parameter.
In this sentence what is bound to the instance. the method, or the self parameter?
This is actually not such a bad question and I'm not sure why it got downvoted so quickly...
Even though Python supports object-oriented, I find it to be much closer to functional-programming languages, one of the reasons for that is that functions are invoked "on" objects, not "by" them.
For example: len(obj) where in a "true" object oriented programing language you'd expect to be able to do something like obj.length()
In regards to the self parameter, you're calling obj.method(other_args) but what really happens under the hood is a translation of this call to: method(obj, other_args) you can see that when the method is declared you're doing it with the self variable passed in as the first argument:
class ...
def method(self, other_args):
...
so it's basically all about the "translation" of obj.method(other_args) to method(obj, other_args)
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
What does "call" mean and do? How would you "call" a function in Python?
When you "call" a function you are basically just telling the program to execute that function. So if you had a function that added two numbers such as:
def add(a,b):
return a + b
you would call the function like this:
add(3,5)
which would return 8. You can put any two numbers in the parentheses in this case. You can also call a function like this:
answer = add(4,7)
Which would set the variable answer equal to 11 in this case.
I'll give a slightly advanced answer. In Python, functions are first-class objects. This means they can be "dynamically created, destroyed, passed to a function, returned as a value, and have all the rights as other variables in the programming language have."
Calling a function/class instance in Python means invoking the __call__ method of that object. For old-style classes, class instances are also callable but only if the object which creates them has a __call__ method. The same applies for new-style classes, except there is no notion of "instance" with new-style classes. Rather they are "types" and "objects".
As quoted from the Python 2 Data Model page, for function objects, class instances(old style classes), and class objects(new-style classes), "x(arg1, arg2, ...) is a shorthand for x.__call__(arg1, arg2, ...)".
Thus whenever you define a function with the shorthand def funcname(parameters): you are really just creating an object with a method __call__ and the shorthand for __call__ is to just name the instance and follow it with parentheses containing the arguments to the call. Because functions are first class objects in Python, they can be created on the fly with dynamic parameters (and thus accept dynamic arguments). This comes into handy with decorator functions/classes which you will read about later.
For now I suggest reading the Official Python Tutorial.
To "call" means to make a reference in your code to a function that is written elsewhere. This function "call" can be made to the standard Python library (stuff that comes installed with Python), third-party libraries (stuff other people wrote that you want to use), or your own code (stuff you wrote). For example:
#!/usr/env python
import os
def foo():
return "hello world"
print os.getlogin()
print foo()
I created a function called "foo" and called it later on with that print statement. I imported the standard "os" Python library then I called the "getlogin" function within that library.
when you invoke a function , it is termed 'calling' a function .
For eg , suppose you've defined a function that finds the average of two numbers like this-
def avgg(a,b) :
return (a+b)/2;
now, to call the function , you do like this .
x=avgg(4,6)
print x
value of x will be 5 .
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I don't know what type it is. How do I check and print it out to console?
a type is basically a value kind and operations that are valid on that value
type(object) #gives you the type
if you want to test for a type
import types
class foo(object):
pass
>>> foo is types.ClassType # test if foo is a class
True
Call the type() function. See the types module for a list of type names you can use with type().
type(variable) will tell you what type something is.
While you can use type() to perform introspection I have to wonder what you're really trying to accomplish.
In Python it's considered to be far better practice to focus on object behavior ... API ... than on type.
Do you care if the object at hand is a Foo() ... or will some subclass of Foo() or some sort of proxy for Foo() (some object containing a Foo()-like object and delegating the requisite functionality to it) do?
The usual advice I see is to use Python's exception handling ... try to use the desired interfaces as if the object is of the correct type and be prepared to handle the exceptions that may be thrown if the object doesn't support that usage. (Most often that will be a TypeError or AttributeError, of course).
Another option is judicious use of hasattr() to see if the object has the necessary attributes (usually methods) to be used like the desired object. (The main caveat there is that there may be method name collisions with completely incompatible semantics in unrelated classes of objects).
Recent versions of Python have introduced the support for "abstract base classes" (ABCs). This basically allows you to use isinstance() and issubclass() in a way that refers to the intended semantics of the objects being tested rather than on their literal instantiation and class hierarchical artifacts. When used with an ABC isinstance() returns a value which indicates whether class supports the signature methods that are considered definitive of the intended semantics.
You can read more about the most commonly used ABCs in the Python Docs: collections module (section 8.3.6).
Unfortunately it's possible you could still confuse the ABCs if you re-use certain method names which have a conventional meaning in the existing Python core or standard libraries.
For example if you create some UI class and define methods of .next() (perhaps to go with some hypothetical .previous()). Doing so, without further effort, would mean that a call like: isinstance(foo, collections.Iterable) would return True even though the semantics you implemented (presumably something like proceeding to the next page in your UI) are completely orthogonal to those that are intended by the collections.Iterable ABC.
I think it's possible to disambiguate by creating some other abstract base class and specifically registering your class as implementing that abstraction. However, I don't know exactly how that would work.
print object.__class__.__name__
Should do the trick.