I have a python function:
def log(text):
print text
saved in Callbacks.py file. Now I want to import it to c++ function and execute. This works fine:
py_fun = import("Callbacks");
py_fun.attr("log")(text);
But I would like to make log function part of a class:
class Logger:
def __init__(self):
self.last_read = -1
def log(self, text):
print text
How can I import it to C++ and create an instance of Logger?
Exactly the way you'd think:
py::object mod = py::import("Callbacks");
py::object logger = mod.attr("Logger")();
Related
I have a script that I am currently working on, named exp1.py and it's located in
/project/exp1.py
In this script, I am trying to call a function named computelikelihood(), which is inside the class Class(), which is in script method.py, in a different directory:
/project/methods/c_CLASS/method.py
So, in my code in exp1.py, I do this:
import sys
sys.path.append('/project/methods/c_CLASS/')
Which gets me to the folder where method.py is located, but when I want to call the Class() from the method.py, so that I get the function computelikelihood(), that I actually want, I get error. I try this:
from method import Class
from Class import computelikelihood
But I get ImportError: No module named Class. Can anyone help?
EDIT
This is how the __init__ of my Class looks like:
class Class:
def __init__(self,e2wl,w2el,label_set):
self.e2wl = e2wl
self.w2el = w2el
self.workers = self.w2el.keys()
self.examples = self.e2wl.keys()
self.label_set = label_set
Since you are trying to use a method from a Class, you should do so via the class. Do not import the function alone as it isn't intended to be used as such:
from method import Class
Class.computelikelihood()
However, this only works if computelikelihood is a static/class method:
class Class:
#classmethod
def computelikelihood(cls):
...
# or
#staticmethod
def computelikelihood():
...
If it's an instance method:
class Class:
def computelikelihood(self):
...
You'll need to first instantiate an object of class Class:
from method import Class
classObject = Class()
classObject.computelikelihood()
How to import classes from all .py in a module with same structure and run by iterating over it. For Example,
module_one:
script_a:
class A:
def __init__(self,**kwargs):
code here
def run(self,**kwargs):
code here
def finish(self,**kwargs):
code here
script_b:
class B:
def __init__(self,**kwargs):
code here
def run(self,**kwargs):
code here
def finish(self,**kwargs):
code here
and so on ...
module_two:
script:
class Run:
def run_all(self,**kwargs):
for class in classes_from_module_one:
c = class()
c.run()
c.finish()
First of all, please note that module refers to python file, while to what you refer as module is usually called a package.
Now, for your problem, you could use some mixture of utilities found in pkgutil, importlib, and inspect or simple dir(). For example, using walk_modules and get_members:
# pack/mod_a.py
class A:
def __init__(self):
pass
def run(self):
print("A run!")
def finish(self):
print("A finished!")
# pack/mod_b.py
class B:
def __init__(self):
pass
def run(self):
print("B run!")
def finish(self):
print("B finished!")
# all.py
from importlib import import_module
from inspect import getmembers
from pkgutil import iter_modules
class Run:
def run_all(self, **kwargs):
modules = iter_modules(["pack"])
for module in modules:
members = getmembers(import_module(f"pack.{module[1]}"))
my_classes = [member for name, member in members if not name.startswith("_")]
for cls in my_classes:
c = cls()
c.run()
c.finish()
if __name__ == '__main__':
run = Run()
run.run_all()
The output is:
A run!
A finished!
B run!
B finished!
However for this solution you have to note, that getmembers will return all members of module - including built-ins, and imported entities to the modules - so you will have to implement your own check to properly filter-out those unwanted (see simple startswith in my example).
I followed advice here on stackoverflow on how to import a class
from a path outside of the root folder:
How to dynamically load a Python class
Does python have an equivalent to Java Class.forName()?
Unfortunately this raises the error:
ValueError: Empty module name
It is my understanding that import should not return an empty module, like the load_source method from imp. So I do not understand this error nor how to approach it.
What am I implementing wrong here?
Could you tilt me into the right direction here?
Thanks!
Code:
klass = __import__('..folder.module.Class_A')
some_object = klass()
class class_B(some_object):
def run(self):
print ('Test OK!')
Imported class (content of module):
class Class_A():
def __init__(self, arg1, *args):
def run(self):
pass
First of all you are not using import correctly.
Option 1:
According to https://docs.python.org/2/library/functions.html#import you should be doing:
klass = __import__('folder.module', globals(), locals(), ['Class_A'], -1)
Now if you want Class_A itself you should do:
some_object = klass.Class_A
Then you can inherit from it using:
class class_B(some_object):
def run(self):
print ('Test OK!')
Option 2:
from folder.module import Class_A
Then you can inherit from it using:
class class_B(Class_A):
def run(self):
print ('Test OK!')
Note: In folder.module folder should be a python package and module should be a python module
i want to move functions because of lot of files, into separate python files.
But if i do it, it dont work.
I tried:
File: server.py:
import os, cherrypy, json
from customers.py import *
class application(object):
def get_webpage(self):
....
def get_data(self):
....
File: customers.py:
import os, cherrypy, json
def get_customer_data(self):
....
I use the python as server,
the data in the function: get_customer_data is in this case not processed, get a 404 Not Found,
means the function is not included in main file (server.py)
I removed the self from get_webpages() because it was not indented, which means it was not part of the class.
application.py:
class application(object):
def __init__(self):
pass
def get_webpage():
print('From application')
customers.py:
from application import *
get_webpage() # From application
You could indent get_webpages() and make it part of the class. The way you call it would change. (I put the self back and capitalized the name of the class.)
application.py:
class Application(object):
def __init__(self):
pass
def get_webpage(self):
print('From application')
customers.py:
from application import *
a = Application()
a.get_webpage() # From application
I'm currently writing some kind of tiny api to support extending module classes. Users should be able to just write their class name in a config and it gets used in our program. The contract is, that the class' module has a function called create(**kwargs) to return an instance of our base module class, and is placed in a special folder. But the isinstance check Fails as soon as the import is made dynamically.
modules are placed in lib/services/name
module base class (in lib/services/service)
class Service:
def __init__(self, **kwargs):
#some initialization
example module class (in lib/services/ping)
class PingService(Service):
def __init__(self, **kwargs):
Service.__init__(self,**kwargs)
# uninteresting init
def create(kwargs):
return PingService(**kwargs)
importing function
import sys
from lib.services.service import Service
def doimport( clazz, modPart, kw, class_check):
path = "lib/" + modPart
sys.path.append(path)
mod = __import__(clazz)
item = mod.create(kw)
if class_check(item):
print "im happy"
return item
calling code
class_check = lambda service: isinstance(service, Service)
s = doimport("ping", "services", {},class_check)
print s
from lib.services.ping import create
pingService = create({})
if isinstance(pingService, Service):
print "why this?"
what the hell am I doing wrong
here is a small example zipped up, just extract and run test.py without arguments
zip example
The problem was in your ping.py file. I don't know exactly why, but when dinamically importing it was not accepting the line from service import Service, so you just have to change it to the relative path: from lib.services.service import Service. Adding lib/services to the sys.path could not make it work the inheritance, which I found strange...
Also, I am using imp.load_source which seems more robust:
import os, imp
def doimport( clazz, modPart, kw, class_check):
path = os.path.join('lib', modPart, clazz + '.py')
mod = imp.load_source( clazz, path )
item = mod.create(kw)
if class_check(item):
print "im happy"
return item