Write a no-op or dummy class in Python - python

Let's say I have code like this:
foo = fooFactory.create()
For various reasons, fooFactory.create() could fail to create an instance of Foo.
If it does, I want fooFactory.create() to return a dummy/no-op object. This object should be completely inert - no matter how it is used, it should not do anything or throw any exceptions. Note that foo does not have methods that return values.
I've considered the following options.
First, create a mock. The upside of this is that it's easy and gives me exactly what I want. The downside is that it feels odd to use a mock in production code. More importantly, I have no control over the mock library and so its behavior could change at some point and break my application.
Second, create a dummy NoopFoo/ DummyFoo class. I then manually implement the methods it needs to support, and just put pass in the method bodies. The upside of that I know it will never break my application. The downside is that if other methods of Foo are used in future, I have to know to update NoopFoo/ DummyFoo ... or my application may break.
Is there a better option than either of these? Note that I'm new to Python so if it involves more advanced Python features, I would appreciate a little more information. Thanks!

You ask for an object that does nothing. An instance of object does precisely that.
def create():
return object()
On the other hand, you might actually want it to do something. You might want it to have methods that execute and return None. You might return an instance of this class:
In [1]: class Nop(object):
...: def nop(*args, **kw): pass
...: def __getattr__(self, _): return self.nop
...:
In [2]: n=Nop()
In [3]: n.foo
Out[3]: <bound method Nop.nop of <__main__.Nop object at 0x7f9fec034650>>
In [4]: n.foo()
In [5]: n.foo(1,2,3)

How about this one:
class MayBeCalled(object):
def __call__(self, *args, **kwargs):
return None
class Dummy(object):
def __getattr__(self, attr):
return MayBeCalled()
def __setattr__(self, attr, val):
pass
a = Dummy()
print a.nn
<__main__.MayBeCalled object at 0x103ca9a90>
print a.nn()
None
a.nn = 23
print a.nn()
None
A Dummy object responds to any attribute access doing nothing.

The previous answers with dummy objects don't work with nested attributes/methods. Here is my solution:
class Dummy:
def __init__(*args, **kwargs):
pass
def __call__(self, *args, **kwargs):
return self
def __getattr__(self, *args, **kwargs):
return self
Now we can access nested attributes and methods:
>>> d = Dummy()
>>> d.my_attr
<__main__.Dummy object at 0x10d007160>
>>> d.my_method()
<__main__.Dummy object at 0x10d007160>
>>> d.my_attr.my_method()
<__main__.Dummy object at 0x10d007160>
>>> d.my_attr.my_other_attr
<__main__.Dummy object at 0x10d007160>

Consider the nop package, available via pip install nop. Please do not use the mock package instead (except in tests) because it stores call history!
from nop import NOP
dummy = NOP()
dummy.foo()
NOP
dummy.foo().bar()
NOP
dummy.foo('x', 'y')
NOP
dummy.foo('x', 'y', z=3)
NOP
type(_)
<class 'nop.nop_base.NOP'>
Its source code is here.

Related

Python wrapper get wrapped object

I do have a wrapperclass for a specific object giving it some extra methods.
However this object (wrapped or not) is often passed as an argument. In this case I want to past the original (wrapped) object allways.
Is there a way (I guess magic method) to overwrite what is coming back if I do the following in print:
class Foo:
pass
C = Foo()
print(C)
I do now that this is actually calling __repr__ (which needs to be a str). If I do the same for a function call
def Bar(obj):
pass
does get Bar a string or the actual class here?
How I wrap the object:
class Wrapper:
def __init__(self, obj):
self._obj = obj
def __getattr__(self, attr):
orig_attr = self._obj.__getattribute__(attr)
if callable(orig_attr):
def hooked(*args, **kwargs):
result = orig_attr(*args, **kwargs)
# prevent wrapped_class from becoming unwrapped
if result == self._obj:
return self
return result
return hooked
else:
return orig_attr
So if do:
C_wrapped = Wrapper(C)
and than
Bar(C_wrapped)
if would actually have it to act as
Bar(C)
even if pass C_wrapped
The solution i found is that the function Bar (or object in my case) needs to check if it gets a wrapped or unwrapped object. If it is wrapped, Bar unwraps it.
The downside is this induces coupling.

Get method of a class in the order that it was in the code

This code:
import inspect
class Obj():
def c(self):
return 1
def b(self):
return 2
def a(self):
return 3
o = Obj()
for name, value in inspect.getmembers(o, inspect.ismethod):
print str(value())+" "+name
print:
3 a
2 b
1 c
Because of inspect.getmembers return all the members of an object in a list of (name, value) pairs sorted by name, as you can read in https://docs.python.org/2/library/inspect.html#inspect.getmembers
But I want to get that list in the same order that the members was written in the code, in other words, the output would be:
1 c
2 b
3 a
Is any way to do that?
Thanks
No. Class members are not ordered. They are gathered into a dictionary, immediately losing order. You can resort to tricks like parsing the source, but it will break easily. For starters, the source could not be available.
[edit: it seems python3 allows more flexibility in class creation, making it possible to customize the way class members are gathered, if you are on python3 only, that's probably a better approach]
If changing the code is not a problem, you can use a decorator though:
import inspect
def track_order(fn):
fn.order = track_order.idx
track_order.idx += 1
return fn
track_order.idx = 0
class Obj(object):
#track_order
def c(self):
return 1
#track_order
def b(self):
return 2
#track_order
def a(self):
return 3
o = Obj()
methods = sorted((item
for item in inspect.getmembers(o, inspect.ismethod)),
key=lambda item: item[1].order)
for name, value in methods:
print str(value())+" "+name
The decorator adds an idx attribute to all methods that pass through it.
This makes use of the fact that python has first-class functions.
$ python test.py
1 c
2 b
3 a
Note: this is the method used by Django to keep track of form and model fields order. Only, they don't need a decorator because fields' classes have the instanciation order attribute built-in (it is named creation_counter).
When creating an object, all of its attributes are contained in another specialized attribute in the object called __dict__, which as the name suggests is just a normal Python non-ordered dictionary, hence they are not guaranteed to be stored in the same fashion they were added in. When retrieving the values in __dict__ using getmembers(), Python automatically reorganizes the dictionary when printing it in order to make some logical sense.
To combat this, something must be done to turn the regular Python dictionary __dict__ into some sort of ordered one.
This can be done a number of ways, for simplicity's sake, I will assume you are using Python 3.
Using the collections package, you can obtain an OrderedDict, which is exactly the technology we require for such an issue. Prepare this ordered dictionary for use in a metaclass for the class which needs ordered members to be stored, copy over the members, and finally access this new OrderedDict when wanting to print out said members.
This can be seen in action in this Stack Overflow answer.
In cpython the code is compiled down to bytecode for the VM. And the functions have a __code__ attribute, which is a code object. The code object has a co_firstlineno attribute, which is the first line in Python source code. (Detailed in the inspect module.)
If you know your methods are all in source code, and you know you are using cpython, you could use this as a sort key. But it seems awful shaky if you don't know these things.
members = [ (name,meth) for name, meth in inspect.getmembers(o, inspect.ismethod)]
members = sorted(members, key=lambda t: t[1].__code__.co_firstlineno)
print '\n'.join(m[0] for m in members)
Hm, this is very hacky, but basically I inspect the source directly and use re to find method names. This solution is pretty brittle, though, and it doesn't deal with inheritance, but maybe it works for you. Assuming I've saved your class definition in a file named test.py:
>>> import test
>>> import re
>>> findmethods = re.compile(r" def (.+)\(")
>>> findmethods.findall(inspect.getsource(test.Obj))
['c', 'b', 'a']
>>>
def print_class_methods_by_order(class_object):
for attr in class_object.__dict__:
if callable(getattr(class_object, attr)):
print(attr)
class MyObject:
def c(self):
pass
def a(self):
pass
def b(self):
pass
output:
>>> print_class_methods_by_order(MyObject)
c
a
b
Also works with decorators:
def print_class_methods_by_order(class_object):
for attr in class_object.__dict__:
if callable(getattr(class_object, attr)):
print(attr)
def my_decorator(func):
def wrapper(*args, **kwargs):
print("my_decorator")
func(*args, **kwargs)
return wrapper
class MyObject:
#my_decorator
def c(self):
pass
#my_decorator
def a(self):
pass
#my_decorator
def b(self):
pass
output:
>>> print_class_methods_by_order(MyObject)
c
a
b
And also works with "class" decorator (not sure there is any difference compared to the previous case):
def print_class_methods_by_order(class_object):
for attr in class_object.__dict__:
if callable(getattr(class_object, attr)):
print(attr)
def decorate_all(decorator):
def decorate(cls):
for attr in cls.__dict__:
if callable(getattr(cls, attr)):
setattr(cls, attr, decorator(getattr(cls, attr), cls))
return cls
return decorate
def my_decorator(func, cls):
def wrapper(*args, **kwargs):
print("my_decorator")
fn = func(*args, **kwargs)
return fn
return wrapper
#decorate_all(my_decorator)
class MyObject:
def c(self):
pass
def a(self):
pass
def b(self):
pass
output:
>>> print_class_methods_by_order(MyObject)
c
a
b

"Programmatically" add stuff to a class?

I'm writing a class that has a dict containing int to method mappings. However setting the values in this dict results in the dict being populated with unbound functions.
class A:
def meth_a: ...
def meth_b: ...
...
map = {1: meth_a, 2: meth_b, ...}
for int in ...:
map[int] = meth_x
This doesn't work for a few reasons:
The methods aren't bound when the class is initialized because they're not in the class dict?
I can't bind the methods manually using __get__ because the class name isn't bound to any namespace yet.
So:
How can I do this?
Do I have to drop out of the class and define the dict after the class has been initialized?
Is it really necessary to call __get__ on the methods to bind them?
Update0
The methods will be called like this:
def func(self, int):
return self.map[int]()
Also regarding the numeric indices/list: Not all indices will be present. I'm not aware that one can do list([1]=a, [2]=b, [1337]=leet) in Python, is there an equivalent? Should I just allocate a arbitrary length list and set specific values? The only interest I have here is in minimizing the lookup time, would it really be that different to the O(1) hash that is {}? I've ignored this for now as premature optimization.
I'm not sure exactly why you're doing what you're doing, but you certainly can do it right in the class definition; you don't need __init__.
class A:
def meth_a(self): pass
m = {1: meth_a}
def foo(self, number):
self.m[number](self)
a = A()
a.foo(1)
An "unbound" instance method simply needs you to pass it an instance of the class manually, and it works fine.
Also, please don't use int as the name of a variable, either, it's a builtin too.
A dictionary is absolutely the right type for this kind of thing.
Edit: This will also work for staticmethods and classmethods if you use new-style classes.
First of all Don't use variable "map" since build in python function map will be fetched.
You need to have init method and initialize your dictionary in the init method using self. The dictionary right now is only part of the class, and not part of instances of the class. If you want instances of the class to have the dictionary as well you need to make an init method and initialize your dictionary there. So you need to do this:
def __init__(self):
self.mymap[int] = self.meth_x
or if you want the dictionary to be a class variable, then this:
def __init__(self):
A.mymap[int] = self.meth_x
It's not totally clear just what you're trying to do. I suspect you want to write code something like
class Foo(object):
def __init__(self, name):
self.name = name
def method_1(self, bar):
print self.name, bar
# ... something here
my_foo = Foo('baz')
my_foo.methods[1]('quux')
# prints "baz quux"
so, that methods attribute needs to return a bound instance method somehow, but without being called directly. This is a good opportunity to use a descriptor. We need to do something that will return a special object when accessed through an instance, and we need that special object to return a bound method when indexed. Let's start from the inside and work our way out.
>>> import types
>>> class BindMapping(object):
... def __init__(self, instance, mapping):
... self.instance, self.mapping = instance, mapping
...
... def __getitem__(self, key):
... func = self.mapping[key]
... if isinstance(func, types.MethodType):
... return types.MethodType(func.im_func, self.instance, func.im_class)
... else:
... return types.MethodType(func, self.instance, type(self))
...
We're just implementing the barest minimum of the mapping protocol, and deferring completely to an underlying collection. here we make use of types.MethodType to get a real instance method when needed, including binding something that's already an instance method. We'll see how that's useful in a minute.
We could implement a descriptor directly, but for the purposes here, property already does everything we need out of a descriptor, so we'll just define one that returns a properly constructed BindMapping instance.
>>> class Foo(object):
... def method_1(self):
... print "1"
... def method_2(self):
... print "2"
...
... _mapping = [method_1, method_2]
...
... #property
... def mapping(self):
... return BindMapping(self, self._mapping)
...
Just for kicks, we also throw in some extra methods outside the class body. Notice how the the methods added inside the class body are functions, just like functions added outside; methods added outside the class body are actual instance methods (although unbound).
>>> def method_3(self):
... print "3"
...
>>> Foo._mapping.append(method_3)
>>> Foo._mapping.append(Foo.method_1)
>>> map(type, Foo._mapping)
[<type 'function'>, <type 'function'>, <type 'function'>, <type 'instancemethod'>]
And it works as advertised:
>>> f = Foo()
>>> for i in range(len(f._mapping)):
... f.mapping[i]()
...
1
2
3
1
>>>
This seems kind of convoluted to me. What is the ultimate goal?
If you really want do to this, you can take advantage of the fact that the methods are alreaday contained in a mapping (__dict__).
class A(object):
def meth_1(self):
print("method 1")
def meth_2(self):
print("method 2")
def func(self, i):
return getattr(self, "meth_{}".format(i))()
a = A()
a.func(2)
This pattern is found in some existing library modules.

Access a subset of functions of a Python class

Using a class that has an xmlrpc proxy as one of it's object's properties
def __init__(self):
self.proxy = ServerProxy(...)
# ...
I'm trying to ease the use of some of the proxy's functions. Only a subset of the proxy functions are supposed to be used and I thus thought of creating a set of tiny wrapper functions for them like
def sample(self):
""" A nice docstring for a wrapper function. """
self.proxy.sample()
Is there a good way of getting a list of all the wrapper functions? I'm thinking about something like dir(), but then I would need to filter for the object's wrapper functions. xmlrpc introspection (http://xmlrpc-c.sourceforge.net/introspection.html) doesn't help much either since I don't want to use/ provide all the server's functions.
Maybe setting an attribute on the wrappers together with a #staticmethod get_wrappers() would do the trick. Having a _wrapper suffix is not appropriate for my use case. A static list in the class that keeps track of the available is too error prone. So I'm looking for good ideas on how to best getting a list of the wrapper functions?
I'm not 100% sure if this is what you want, but it works:
def proxy_wrapper(name, docstring):
def wrapper(self, *args, **kwargs):
return self.proxy.__getattribute__(name)(*args, **kwargs)
wrapper.__doc__ = docstring
wrapper._is_wrapper = True
return wrapper
class Something(object):
def __init__(self):
self.proxy = {}
#classmethod
def get_proxy_wrappers(cls):
return [m for m in dir(cls) if hasattr(getattr(cls, m), "_is_wrapper")]
update = proxy_wrapper("update", "wraps the proxy's update() method")
proxy_keys = proxy_wrapper("keys", "wraps the proxy's keys() method")
Then
>>> a = Something()
>>> print a.proxy
{}
>>> a.update({1: 42})
>>> print a.proxy
{1: 42}
>>> a.update({"foo": "bar"})
>>> print a.proxy_keys()
[1, 'foo']
>>> print a.get_proxy_wrappers()
['proxy_keys', 'update']
Use xml-rpc introspection to get the server list and intersect it with your object's properties. Something like:
loc = dir(self)
rem = proxy.listMethods() # However introspection gets a method list
wrapped = [x for x in rem if x in loc]

Namespaces inside class in Python3

I am new to Python and I wonder if there is any way to aggregate methods into 'subspaces'. I mean something similar to this syntax:
smth = Something()
smth.subspace.do_smth()
smth.another_subspace.do_smth_else()
I am writing an API wrapper and I'm going to have a lot of very similar methods (only different URI) so I though it would be good to place them in a few subspaces that refer to the API requests categories. In other words, I want to create namespaces inside a class. I don't know if this is even possible in Python and have know idea what to look for in Google.
I will appreciate any help.
One way to do this is by defining subspace and another_subspace as properties that return objects that provide do_smth and do_smth_else respectively:
class Something:
#property
def subspace(self):
class SubSpaceClass:
def do_smth(other_self):
print('do_smth')
return SubSpaceClass()
#property
def another_subspace(self):
class AnotherSubSpaceClass:
def do_smth_else(other_self):
print('do_smth_else')
return AnotherSubSpaceClass()
Which does what you want:
>>> smth = Something()
>>> smth.subspace.do_smth()
do_smth
>>> smth.another_subspace.do_smth_else()
do_smth_else
Depending on what you intend to use the methods for, you may want to make SubSpaceClass a singleton, but i doubt the performance gain is worth it.
I had this need a couple years ago and came up with this:
class Registry:
"""Namespace within a class."""
def __get__(self, obj, cls=None):
if obj is None:
return self
else:
return InstanceRegistry(self, obj)
def __call__(self, name=None):
def decorator(f):
use_name = name or f.__name__
if hasattr(self, use_name):
raise ValueError("%s is already registered" % use_name)
setattr(self, name or f.__name__, f)
return f
return decorator
class InstanceRegistry:
"""
Helper for accessing a namespace from an instance of the class.
Used internally by :class:`Registry`. Returns a partial that will pass
the instance as the first parameter.
"""
def __init__(self, registry, obj):
self.__registry = registry
self.__obj = obj
def __getattr__(self, attr):
return partial(getattr(self.__registry, attr), self.__obj)
# Usage:
class Something:
subspace = Registry()
another_subspace = Registry()
#MyClass.subspace()
def do_smth(self):
# `self` will be an instance of Something
pass
#MyClass.another_subspace('do_smth_else')
def this_can_be_called_anything_and_take_any_parameter_name(obj, other):
# Call it `obj` or whatever else if `self` outside a class is unsettling
pass
At runtime:
>>> smth = Something()
>>> smth.subspace.do_smth()
>>> smth.another_subspace.do_smth_else('other')
This is compatible with Py2 and Py3. Some performance optimizations are possible in Py3 because __set_name__ tells us what the namespace is called and allows caching the instance registry.

Categories

Resources