I have written a library that is roughly structured like this:
# file library/module/core.py
class MyClass:
backend = DesignatedBackend()
# file library/backends/backend_A.py
class DesignatedBackend:
who = "I'm backend A"
# file library/backends/backend_B.py
class DesignatedBackend:
who = "I'm backend B"
Then in IPython, or when running a script I would like to be able to write:
>>> from library.module.core import MyClass
>>> import library.backends.backend_A # or something
>>> print(MyClass().backend.who)
I'm backend A
i.e. I would like to set which classes are available in the global namespace of the library by issuing an appropriate import statement.
Because your core file doesn't import anything it can't resolve what DesignatedBackEnd is. Even if you could somehow inject the DesignatedBackEnd into the namespace of core it would be too late, as the core module can't exist until you import it, and that import will fail.
You could 'contrive' to have a factory method in core, so you import the core module, inject into the namespace and then dynamically create the appropriate class.
But the nicest way to do this is use composition :
# file library/module/core.py
class MyClass:
def __init__(self, backend_type):
self.backend = backend_type()
# file library/backends/backend_A.py
class DesignatedBackend:
who = "I'm backend A"
# file library/backends/backend_B.py
class DesignatedBackend:
who = "I'm backend B"
This way you can do :
>>> from library.module.core import MyClass
>>> from library.backends.backend_A import DesignatedBacEnd # or something
>>> print(MyClass(DesignatedBackEnd).backend.who)
I'm backend A
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()
I am using unittest module for writing tests.
I need to test initialization of the object inside a testcase using different inputs.
For this purpose I am importing the class inside setUp(). But when I try to use the class inside test_*() functions, I get this error - NameError: name 'Example' is not defined
Here is my code sample-
import unittest
class TestExample(unittest.TestCase):
def setUp(self):
import Example
def test_sample_function(self):
e = Example(1,2)
I know that I can simply import the class at top of the script. But I do not want to do that. I need to import it only during setup of the testscript.
Looking for some help here.
import unittest
class TestExample(unittest.TestCase):
def setUp(self):
import Example
self.Example = Example
def test_sample_function(self):
e = self.Example(1,2)
There's no reason to import the module in setUp. The module is still available globally in sys.modules, but you've only bound it to a local name that goes away after setUp returns. Just import it globally.
import unittest
import Example
class TestExample(unittest.TestCase):
def test_sample_function(self):
e = Example(1,2)
I have a File Field in my Plone product that I want to allow the user to "Turn Off" blob storage. The file will be stored elsewhere. I can't seem to do it.
Below is my attempt. I can't get Products.Archetypes.Field.ObjectField.setStorage() to recognize that this 'noStorage' instance "provides" IStorage.
Much inconsequential code has been removed for brevity, but the complete source can be found at https://github.com/flipmcf/rfa.kaltura
The Archetype schema includes "ATBlob.schema" to pull in the "File" field, then:
class KalturaVideo(ATBlob, KalturaBase.KalturaContentMixin):
nostorage = NoStorage()
directlyProvides(nostorage, INoStorage)
def __init__(self, oid, **kwargs):
if settings.storageMethod == u"No Local Storage":
import pdb; pdb.set_trace() #
#(Pdb) IStorage.providedBy(self.nostorage)
#True
self.getField('file').setStorage(self, self.nostorage)
My Storage class and interface is really boring:
from zope.interface import implements
from ZODB.interfaces import IStorage
from zope.component.zcml import interface
from zope.interface import Interface
class INoStorage(IStorage):
pass
class NoStorage(object):
"""Completely skip storage on Plone."""
implements(INoStorage)
def __init__(self):
pass
def close():
pass
def getName():
return "NoStorage - Blackhole"
#etc... lots of implemented methods that do nothing.
configure.zcml in the 'storage' package also:
<adapter
factory=".storage.NoStorage"
provides=".storage.INoStorage"
for="Products.Archetypes.interfaces.field.IObjectField"
/>
<adapter
factory=".storage.NoStorage"
provides=".storage.IStorage"
for="Products.Archetypes.interfaces.field.IObjectField"
/>
Now, within the setStorage() method of Products.Archetypes.Field.ObjectField:
def setStorage(self, instance, storage):
import pdb; pdb.set_trace()
#(Pdb) IStorage.providedBy(storage)
#False
#HeadDesk
if not IStorage.providedBy(storage):
raise ObjectFieldException, "Not a valid Storage method"
And when I debug, IStorage.providedBy(storage) returns False
Why would it return False in setStorage and True in the calling code? Am I not registering the interface correctly?
Note that in the module Products.Archetypes.Field, the IStorage instance there is actually sourced from this:
from Products.Archetypes.interfaces.storage import IStorage
Comparing the interface resolution order (via __iro__) we get
>>> from pprint import pprint as pp
>>> pp(ZODB.interfaces.IStorage.__iro__)
(<InterfaceClass ZODB.interfaces.IStorage>,
<InterfaceClass zope.interface.Interface>)
>>> pp(Products.Archetypes.interfaces.storage.IStorage.__iro__)
(<InterfaceClass Products.Archetypes.interfaces.storage.IStorage>,
<InterfaceClass zope.interface.Interface>)
As the INoStorage was subclassed from ZODB.interfaces.IStorage, and that interface class isn't the parent of Products.Archetypes.interfaces.storage.IStorage which the setStorage calls providedBy on, the NoStorage class as define will not satisfy that check. To solve this, just have INoStorage simply inherit from the Archetype version of the IStorage and implement all its methods and it should work as intend.
That said, you could simply your code somewhat further with regards to the way you provide the interfaces, see this example:
>>> class INoStorage(Products.Archetypes.interfaces.storage.IStorage):
... pass
...
>>> class NoStorage(object):
... zope.interface.implements(INoStorage)
...
>>> nostorage = NoStorage()
>>> Products.Archetypes.interfaces.storage.IStorage.providedBy(nostorage)
True
Inheritances of the Interface subclasses will persist correctly through without extra directlyProvides definitions, so you can just drop that extra call inside the KalturaVideo class definition. Naturally, you can just do from ... import IStorage and simply that to class INoStorage(IStorage). The example was done so to make things more explicitly visible.
My (simplified) project layout is as follows:
/__init__.py
/test.py
/lib/__init__.py
/lib/client.py
my test.py is simply:
import lib.client
A = client()
A.Test()
and my lib\client.py begins as follows:
import ui #(another class in the lib dir)
class client(object):
"""
(Blah)
"""
UI = None
def __init__():
UI = ui()
def Test():
print "Success"
When I attempt to run test.py, I can step into the code and see that the definitions in client are parsed, however, when I get to the line where I instantiate a client, I get the following exception:
NameError: name 'client' is not defined
if I change that line to be:
A = lib.client()
Then I get
'module' object is not callable
What am I missing?
the lib.client object you have after import lib.client is the module, not the class. To instantiate the class you need to call the class in the module object:
A = lib.client.client()
or, as #rantanplan said, import the class from the module
from lib.client import client
A = client()
I just understood that you do the imports the Java way.
In python when you do :
import lib.client
You don't make available all the definitions in that module. You just
made available the actual module - the client.py
So either you keep the import scheme as you have now and do
import lib.client
A = lib.client.client()
or
from lib.client import client
A = client()
Also I suggest you name your python classes with capitalized camelcase
i.e.
class Client(object):
As it is the python convention.
Either it's lack of sleep but I feel silly that I can't get this. I have a plugin, I see it get loaded but I can't instantiate it in my main file:
from transformers.FOMIBaseClass import find_plugins, register
find_plugins()
Here's my FOMIBaseClass:
from PluginBase import MountPoint
import sys
import os
class FOMIBaseClass(object):
__metaclass__ = MountPoint
def __init__(self):
pass
def init_plugins(self):
pass
def find_plugins():
plugin_dir = os.path.dirname(os.path.realpath(__file__))
plugin_files = [x[:-3] for x in os.listdir(plugin_dir) if x.endswith("Transformer.py")]
sys.path.insert(0, plugin_dir)
for plugin in plugin_files:
mod = __import__(plugin)
Here's my MountPoint:
class MountPoint(type):
def __init__(cls,name,bases,attrs):
if not hasattr(cls,'plugins'):
cls.plugins = []
else:
cls.plugins.append(cls)
I see it being loaded:
# /Users/carlos/Desktop/ws_working_folder/python/transformers/SctyDistTransformer.pyc matches /Users/carlos/Desktop/ws_working_folder/python/transformers/SctyDistTransformer.py
import SctyDistTransformer # precompiled from /Users/carlos/Desktop/ws_working_folder/python/transformers/SctyDistTransformer.pyc
But, for the life of me, I can't instantiate the 'SctyDistTransformer' module from the main file. I know I'm missing something trivial. Basically, I want to employ a class loading plugin.
To dymically load Python modules from arbitrary folders use imp module:
http://docs.python.org/library/imp.html
Specifically the code should look like:
mod = imp.load_source("MyModule", "MyModule.py")
clz = getattr(mod, "MyClassName")
Also if you are building serious plug-in architecture I recommend using Python eggs and entry points:
http://wiki.pylonshq.com/display/pylonscookbook/Using+Entry+Points+to+Write+Plugins
https://github.com/miohtama/vvv/blob/master/vvv/main.py#L104