When I import a module that has a class, what code is executed when that class is first read and the class object created? Is there any way I can influence what happens?
Edit: I realize my question might be a bit too general...
I'm looking for something more low-level which will allow me to do introspection from C++. I extend my C++ application with Python. I have some classes that are defined in C++ and exposed in Python. The user can inherit from these classes in the scripts and I want to be able to grab details about them when they are first defined.
Many possible things can happen. The most basic:
The contents of the class block are executed when the it is first read.
To see this in action, this example:
class Foo(object):
print "bar"
def __init__(self):
print "baz"
Will print bar when the module is imported.
If a class has a metaclass defined, the metaclasses __new__ function will run after the classes block of code is run.
Example:
class MyMeta(type):
def __new__(mcs, name, bases, kwargs):
print "I'm the metaclass, just checking in."
return type.__new__(mcs, name, bases, kwargs)
class Foo(object):
__metaclass__ = MyMeta
print "I'm the Foo class"
Output:
I'm the Foo class
I'm the metaclass, just checking in.
I'm sure other bits can run as well, these are just what I am familiar with.
Defining a class A that inherits from B and C executes: A = type('A', (B, C), m where m is a dictionary containing the members of the class.
You can influence the process using metaclass programming. There are no shortage of blog posts and tutorials on the subject.
You might be interested in metaclasses, which are classes that control the creation of classes.
The code in a class definition is executed just like any other code but any variables created (including function definitions) will be in the context of the class instead of global. This means that you can change the class definition dynamically by adding conditional code:
class A(object):
if 1==2:
def f(self):
print "the world has gone mad"
else:
def f(self):
print "sanity rules"
>>> a = A()
>>> a.f()
sanity rules
>>>
However I have never seen this done, and can't think of a reason for doing it - it feels rather unpythonic.
As others have pointed out there are lots of other ways of modifying the behaviour of a class including metaclasses, inheritance and class decorators.
Python is interpreted, so when a Python module is imported any class code at the module level is run, along with those classes' meta-classes -- this is so the classes will exist.
C++ is compiled: the classes already exist when they are imported; there is no way to control how they are created as they are already created.
Related
I have a python class such as the following
def function1():
return=1+1
class Collection()
...
#classmethod
def get_allobjects(cls):
..logic here..
retval = function1()
function1 is encapsulated from the outerlying class but needs to be available for get_allobjects. What would be the best way to define this function? Should it be defined as a class method or can it be left as a stand alone function inside of the same python file (defined before the class?)? Any advice or pointers on style would be appreciated.
Thanks,
Jeff
It really depends on the context. Your options:
a global function
As in your example code. This would make the function visible to all who import your module, just as the class itself is.
def function1():
return=1+1
function1()
a global, but 'hidden' function
Use a name that starts with an _ to indicate that it's not supposed to be used externally. People still can, but it would generate warnings.
def _function1():
return=1+1
_function1()
a class method
This really only makes sense if the method need access to something on the class, which is why it is passed a reference to the class.
#classmethod
def function1(cls):
return=1+cls.some_class_attribute
self.function1()
a static method
This may be what you're looking for, as it limits access to the function to whoever has access to the class (or an instance), but it does not allow access to the class or instances itself.
#staticmethod
def function1():
return=1+1
self.function1()
and finally, you may want to hide the class or static method
For the same reason as before, perhaps you only want methods in the class itself to have access, not everyone who has a hold of the class or an instance.
#staticmethod
def _function1():
return=1+1
self._function1()
It all depends on how visible you want the function to be and whether or not the logic of the function is really independent of the class, or whether it only makes sense in context of the class.
There's more options still, for example defining the function as a sub-function of the method itself, but that's only really sensible if the construction of the function itself somehow depends on the state of the class/object when it is constructed.
I am vrey new to python and have to work with a given code (not my implementation), with very limited accesses (no debugger, screen prints and such).
Assuming I have the following class:
class foo ():
def __init__(self, u, v):
#some flow
def main():
#some flow
x=1
return x
main() and foo() are in the same "file.py" file. are they connected?
and I instantiate it in the following way:
import file as A
MyFoo=A.main()
In oppose to:
MyFoo=foo()
Did I call upon the __init__ function?
If so how? I see no point where it is stimulated.
If it was indeed called (and here lies the big questions) how do I assert values for u & v?
I have tried an online compiler and still didn't manage, changing u & v values. I also read this to try and understand instantiation process in python.
It would help if you stated your overall goal, but I can offer this information: __init__ is called by Python to initialize new instances of a class. If you want it called, you should say "myfoo = foo(myu,myv)". That will cause Python to invoke __new__, which will invoke __init__ for you. You should do something with u and v inside __init__, perhaps assigning them to instance attributes, like this: "self.u = u".
Here, main() is just a normal, unbound function, not an instance function or a class function of foo, not even a static function inside foo's scope, and definitely not a mainline in the C and Java sense of "mainline." If you want it to create an instance of foo, you should put "myfoo = foo(myu,myv)" inside main(project). However, the fact that you named the function "main" suggests you don't know how mainlines work in Python. See here: What does if __name__ == "__main__": do?
When you import file as A and then say "MyFoo = A.main()", all you are doing is invoking main(), which just returns 1 and does nothing with class foo. Try printing out MyFoo. You will see that it got the return value of main (which was 1), and thus MyFoo has nothing to do with class foo.
The way you are naming things suggests you are very confused. Please say your overall goal, so we can help you more.
There is some library written on Python (2.x). Its code can't be changed. Inside of the lib there is class A. I need modify behaviour of A::method(). There are a lot of other classes: class B, class C and so on (they all belongs to the lib as well). They all uses class A in some way - no matter. All that means that I can't inherit class A and override the method A::method().
As I know - there is Python-Decorators-technic that should be used for it. But how exactly? Could you show some sample of such solution???
Have you tried:
from lib import A
def my_method(instance, *args, **kwargs):
some_code_here()
A.method = my_method
I'm a C++ programmer learning Ruby. In a beginner book I read:
"A class is itself an object, even if you don’t directly instantiate it."
I don't know how to interpret that.
In C++, with the exception of typeid et al, there's no language-visible runtime representation of a class. You can say class Foo {};, but then you can't say &Foo. (You can get the typeid / address of the typeinfo object, which is a bastardized version of a class object).
In Ruby, classes are objects. Anything you can do with an object, you can do with a class since it is an object. For example, in Ruby you can foo.send(...) to any object foo. Since a class is an object, you can just as well as Foo.send(...).
The part about "you didn't instanciate it" refers to the fact that usually you say foo = Foo.new in Ruby but you don't need to say that for classes. The class object is created by the runtime. (In fact, class Foo; end in Ruby is pretty similar to Foo = Class.new.)
In Ruby, everything is an object. That includes classes. So when you declare
class Thing
end
You've made an instance of the Class class called Thing. It's identical to
Thing = Class.new
which would be "directly instantiating" the instance of Class.
Everything in Ruby is an object, even the classes themselves.
class Test
def self.foo
"bar"
end
def yin
"yang"
end
end
# This creates a new instance and calls #yin
Test.new.yin # => "yang"
# This calls the #foo method on the Test class object.
Test.foo # => "bar"
In some other languages, you have something called 'abstract classes'. These things are not objects themselves and can't really do anything. They're really more like a template for creating an actual object. An actual object can do things like run methods, accept arguments, etc. An abstract class can't do any of that and exists mainly to create a real object. When an object is created from them, it's called 'instantiating' an object.
Now in ruby, you don't have abstract classes. The class you use to derive objects from (instantiate) is sort of like an abstract class in some ways. But unlike abstract classes, this class in ruby can already do things itself.
This is what the statement you quoted "A class is itself an object, even if you don’t directly instantiate it" is trying to make clear. It isn't virtual in the sense of an abstract class. Rather it's already a full fledged object.
All this really means is that you can treat Classes just as you can instances of these classes.
class Animal; end
bird = Animal.new
You can now work with Animal just as you could with bird.
e.g.
Animal.methods => 'list of methods'
bird.methods => 'list of methods'
That's all there is to it really.
I have some C++ I have exposed to Python through SWIG. In there is a base class with a single pure virtual function.
In Python, I import my module and define a class that uses the abstract class as base.
import mymodule
class Foo(mymodule.mybase):
...
In that module is also a manager class, I want to add my new defined class to the manager.
m = mymodule.mymanager()
m.add(Foo())
Definition of add:
void add(mybase* b) { ... }
Didn't work as I would expect:
TypeError: in method 'mymanager_add', argument 2 of type 'mymodule::mybase *'
What did I miss? It seems it's not sure that my Foo class is a "mybase". I tried adding a call to the base class constructor in Python but that didn't work, said the class was abstract.
def __init__(self):
mymodule.mybase.__init__(self)
My guess is that Foo is not derived from mybase in the eyes of the C++ environment. I'm not sure if SWIG can pull this off since it requires a bidirectional understanding of inheritance - Python class uses C++ class as base and C++ code recognizes the inheritance relationship. I would take a serious look into Boost.python since it seems to support the functionality that you are after. Here's an entry on wiki.python.org about it.
Not really an answer, but you might have better luck with boost.python. Don't know how much work it would be for you to switch, but you could probably get a simple inheritence test case for your problem going pretty quickly.