I am quite amateur in OOP concepts of python so I wanted to know are the functionalities of self of Python in any way similar to those of this keyword of CPP/C#.
self & this have the same purpose except that self must be received explicitly.
Python is a dynamic language. So you can add members to your class. Using self explicitly let you define if you work in the local scope, instance scope or class scope.
As in C++, you can pass the instance explicitly. In the following code, #1 and #2 are actually the same. So you can use methods as normal functions with no ambiguity.
class Foo :
def call(self) :
pass
foo = Foo()
foo.call() #1
Foo.call(foo) #2
From PEP20 : Explicit is better than implicit.
Note that self is not a keyword, you can call it as you wish, it is just a convention.
Yes they implement the same concept. They serve the purpose of providing a handle to the instance of class, on which the method was executed. Or, in other wording, instance through which the method was called.
Probably someone smarter will come to point out the real differences but for a quite normal user, pythonic self is basically equivalent to c++ *this.
However the reference to self in python is used way more explicitly. E.g. it is explicitly present in method declarations. And method calls executed on the instance of object being called must be executed explicitly using self.
I.e:
def do_more_fun(self):
#haha
pass
def method1(self, other_arg):
self.do_more_fun()
This in c++ would look more like:
void do_more_fun(){
//haha
};
void method1(other_arg){
do_more_fun();
// this->do_more_fun(); // also can be called explicitly through `this`
}
Also as juanchopanza pointed out, this is a keyword in c++ so you cannot really use other name for it. This goes in pair with the other difference, you cannot omit passing this in c++ method. Only way to do it is make it static. This also holds for python but under different convention. In python 1st argument is always implicitly assigned the reference to self. So you can choose any name you like. To prevent it, and be able to make a static method in python, you need to use #staticmethod decorator (reference).
Related
I am trying to mock the call to a function and still have the effect of the function apply. I found the solution using Python wraps, but all examples I found are applied to mocking the member method of a class. In my case, I have a pure function (not defined in a class). This seems to not work with the usual examples, as they require you to instantiate the class first I guess to obtain the real version of the method to pass into wraps.
Can this be done with pure functions?
https://wesmckinney.com/blog/spying-with-python-mocks/
My code:
<this_module.py>
def my_function:
does something important
def test_my_function:
with patch.object("this_module", "my_function", wraps="this_module.my_function")
While trying to use introspection to navigate from strings to classes via some of the suggestions in Convert string to Python class object? I noticed that the given approaches won't work to get at a class in scope local to a function. Consider the following code:
import sys
def f():
class LocalClass:
pass
print LocalClass
print 'LocalClass' in dir(sys.modules[__name__])
which gives output
__main__.LocalClass
False
I'm a bit confused as to why LocalClass seems to belong to the main module according to the class object itself, and yet not accessible through sys.modules. Can someone give an explanation?
And is there a way to generate a class from a string, even if that class is only in non-global scope?
In the function f, LocalClass is indeed local. You can see this by trying __main__.LocalClass and seeing that AttributeError: 'module' object has no attribute 'LocalClass' is raised.
As to why the class returns __main__.LocalClass is because by default, the __repr__ function returns <cls.__module__>.<cls.__name__>.
The reason why dir isn't finding it is because it only looks at the variables defined in its scope. LocalClass is local so it won't show up if you are looking in the main module.
A way to create a class from a string can be done in many ways.
The first and easiest to understand is by using exec. Now you shouldn't just go around using exec for random things so I wouldn't reccomend using this method.
The second method is by using the type function. The help page for it returns type(name, bases, dict). This means you can create a class called LocalClass subclassed by object with the attribute foo set to "bar" by doing type("LocalClass", (object,), {"foo": "bar"}) and catching the returned class in a variable. You can make the class global by doing globals()["LocalClass"] = ...
PS: An easier (not sure if prettier) way to get the main module is by doing import __main__. This can be used in any module but I would generally advise against using this unless you know what you are doing because in general, python people don't like you doing this sort of thing.
EDIT: after looking at the linked question, you dont want to dynamically create a new class but to retrieve a variable given it's name. All the answers in the linked question will do that. I'll leave you up to deciding which one you prefer the most
EDIT2: LocalClass.__module__ is the same as __main__ because that was the module you defined the class. If you had defined it in module Foo that was imported by __main__ (and not actually ran standalone), you would find that __module__ would be "B". Even though LocalClass was defined in __main__, it won't automatically go into the global table just because it is a class - in python, as you might have already known, (almost) EVERYTHING is an object. The dir function searches for all variables defined in a scope. As you are looking in the main scope, it is nearly equivalent to be doing __dict__ or globals() but with some slight differences. Because LocalClass is local, it isn't defined in the global context. If however you did locals() whilst inside the function f, you would find that LocalClass would appear in that list
Perhaps a stupid question:
how can one specify docstring for special functions like __init__ when writing a C extension?
For ordinary methods, method table has provision for docstrings. The following autogenerated documentation is displayed when I try help(myclass):
__init__(...)
x.__init__(...) initializes x; see help(type(x)) for signature
But this is what I want to override.
I think that the most common thing to do is to just stick the definitions for the various functions into tp_doc and just leave it at that. You can then do as it says and look at your object's doc. This is what happens all over the standard library.
You don't really have any option of writing __doc__ on the various slots (tp_init, etc.) because they're wrapped by a wrapper_descriptor when you call PyType_Ready, and the docstring on a wrapper_descriptor is read-only.
I think that it is possible to skip using the slots and add your method (e.g. __init__) to your MemberDefs, but I've never tried that.
I have a C++ class that requires a function pointer in it's constructor (float(*myfunction)(vector<float>*))
I've already exposed some function pointers to Python.
The ideal way to use this class is something like this:
import mymodule
mymodule.some_class(mymodule.some_function)
So I tell Boost about this class like so:
class_<SomeClass>("some_class", init<float(*)(vector<float>*)>);
But I get:
error: no matching function for call to 'register_shared_ptr1(Sample (*)(std::vector<double, std::allocator<double> >*))'
when I try to compile it.
So, does anyone have any ideas on how I can fix the error without losing the flexibility gained from function pointers (ie no falling back to strings that indicate which function to call)?
Also, the main point of writing this code in C++ is for speed. So it would be nice if I was still able to keep that benefit (the function pointer gets assigned to a member variable during initialization and will get called over a million times later on).
OK, so this is a fairly difficult question to answer in general. The root cause of your problem is that there really is no python type which is exactly equivalent to a C function pointer. Python functions are sort-of close, but their interface doesn't match for a few reasons.
Firstly, I want to mention the technique for wrapping a constructor from here:
http://wiki.python.org/moin/boost.python/HowTo#namedconstructors.2BAC8factories.28asPythoninitializers.29. This lets you write an __init__ function for your object that doesn't directly correspond to an actual C++ constructor. Note also, that you might have to specify boost::python::no_init in the boost::python::class_ construction, and then def a real __init__ function later, if your object isn't default-constructible.
Back to the question:
Is there only a small set of functions that you'll usually want to pass in? In that case, you could just declare a special enum (or specialized class), make an overload of your constructor that accepts the enum, and use that to look up the real function pointer. You can't directly call the functions yourself from python using this approach, but it's not that bad, and the performance will be the same as using real function pointers.
If you want to provide a general approach that will work for any python callable, things get more complex. You'll have to add a constructor to your C++ object that accepts a general functor, e.g. using boost::function or std::tr1::function. You could replace the existing constructor if you wanted, because function pointers will convert to this type correctly.
So, assuming you've added a boost::function constructor to SomeClass, you should add these functions to your python wrapping code:
struct WrapPythonCallable
{
typedef float * result_type;
explicit WrapPythonCallable(const boost::python::object & wrapped)
: wrapped_(wrapped)
{ }
float * operator()(vector<float>* arg) const
{
//Do whatever you need to do to convert into a
//boost::python::object here
boost::python::object arg_as_python_object = /* ... */;
//Call out to python with the object - note that wrapped_
//is callable using an operator() overload, and returns
//a boost::python::object.
//Also, the call can throw boost::python::error_already_set -
//you might want to handle that here.
boost::python::object result_object = wrapped_(arg_as_python_object);
//Do whatever you need to do to extract a float * from result_object,
//maybe using boost::python::extract
float * result = /* ... */;
return result;
}
boost::python::object wrapped_;
};
//This function is the "constructor wrapper" that you'll add to SomeClass.
//Change the return type to match the holder type for SomeClass, like if it's
//held using a shared_ptr.
std::auto_ptr<SomeClass> CreateSomeClassFromPython(
const boost::python::object & callable)
{
return std::auto_ptr<SomeClass>(
new SomeClass(WrapPythonCallable(callable)));
}
//Later, when telling Boost.Python about SomeClass:
class_<SomeClass>("some_class", no_init)
.def("__init__", make_constructor(&CreateSomeClassFromPython));
I've left out details on how to convert pointers to and from python - that's obviously something that you'll have to work out, because there are object lifetime issues there.
If you need to call the function pointers that you'll pass in to this function from Python, then you'll need to def these functions using Boost.Python at some point. This second approach will work fine with these def'd functions, but calling them will be slow, because objects will be unnecessarily converted to and from Python every time they're called.
To fix this, you can modify CreateSomeClassFromPython to recognize known or common function objects, and replace them with their real function pointers. You can compare python objects' identity in C++ using object1.ptr() == object2.ptr(), equivalent to id(object1) == id(object2) in python.
Finally, you can of course combine the general approach with the enum approach. Be aware when doing this, that boost::python's overloading rules are different from C++'s, and this can bite you when dealing with functions like CreateSomeClassFromPython. Boost.Python tests functions in the order that they are def'd to see if the runtime arguments can be converted to the C++ argument types. So, CreateSomeClassFromPython will prevent single-argument constructors def'd later than it from being used, because its argument matches any python object. Be sure to put it after other single-argument __init__ functions.
If you find yourself doing this sort of thing a lot, then you might want to look at the general boost::function wrapping technique (mentioned on the same page with the named constructor technique): http://wiki.python.org/moin/boost.python/HowTo?action=AttachFile&do=view&target=py_boost_function.hpp.
I need to create a function to rotate a given matrix (list of lists) clockwise, and I need to use it in my Table class. Where should I put this utility function (called rotateMatrixClockwise) so I can call it easily from within a function in my Table class?
Make it a static function...
add the #staticmethod decorator
don't include 'self' as the first argument
Your definition would be:
#staticmethod
def rotateMatrixClockwise():
# enter code here...
Which will make it callable everywhere you imported 'table' by calling:
table.rotateMatrixClockwise()
The decorator is only necessary to tell python that no implicit first argument is expected. If you wanted to make method definitions act like C#/Java where self is always implicit you could also use the '#classmethod' decorator.
Here's the documentation for this coming directly from the python manual.
Note: I'd recommend using Utility classes only where their code can't be coupled directly to a module because they generally violate the 'Single Responsibility Principle' of OOP. It's almost always best to tie the functionality of a class as a method/member to the class.
If you don't want to make it a member of the Table class you could put it into a utilities module.