Customized Trait built from multiple inheritance - python

I am trying to create a custom trait which represents a unipath.Path object. It seems advantageous to re-use the machinery provided by the File trait, so my thought was to use multiple inheritance.
from unipath import Path
from traits import File
class PathTrait(Path,File):
pass
class A(HasTraits):
p = PathTrait()
However, when i used this via A(p='/tmp/'), A.p does not have any methods associated with the Path object, as i would expect. Should i be implementing get and set methods?

What do you expect A(p='/tmp') should do?
I can tell what you are trying to do but this statement should fail with TypeError if your code was correct. Instead of type error, you are replacing the variable P on the A object, which was previously an instance of PathTrait, with a string.
What you're trying to do is conceptually mixed up. File is a class which represents a trait object. Technically python allows you to extend this object, because python has very little type safety, but it doesn't mean your python class will now suddenly act like a trait.
To define custom traits you will need to use tools designed to operate with traits such as the Trait constructor.

Related

How to change one class in an external package for my use?

I use an external pacakge which I bring in via pip.
This package has a structure as follows:
class OuterThing:
field: Innerthing
def outer_method1(self...
class InnerThing():
def inner_method1(self,...
def inner_method2(self,...
def inner_method3(self,...
I instantiate only OuterThing objects (which then internally instantiate InnerThing objects).
I want the inner thing objects to have all the normal fields and methods, just inner_method1 I need to customise a bit for my use.
What is the shortest way (i.e. the way with the least code) to do this?
I do not want to copy the whole package into my source tree if possible, just "inject" the changes at runtime (but possibly before all instantiations) to the specified method in InnerThing.
In Python, a method is just an attribute of the class object that happens to be a function having self as its first parameter. That means that you can easily replace it by your own function, provided you keep the same signature. You can even call the original method from your own one:
# after having imported InnerThing
_orig_inner_method1 = InnerThing.inner_method1
def _patched_inner_method1(self, ...):
# your own code
...
_orig_inner_method1(self, ...) # eventually call the original method
...
InnerThing.inner_method1 = _patched_inner_method1
From that point, any InnerThing object created will use your patched method.
Python allows you to Monkey Patch code simply by assigning a different function pointer to the function you're trying to replace. This can be done as long as you can grab a reference to the instance of InnerThing at runtime.
In your case, it seems like OuterThing does have a reference to InnerThing so you can do something like this:
def your_implementation_of_inner_method1(self, ...):
# Do stuff
outerThing = OuterThing()
outerThing.field.inner_method1 = your_implementation_of_inner_method1
If you want to dig deeper as to why this is possible, I recommend having a look at the Python documentation for classes. The tl;dr is that methods are actually objects and are stored as fields in instances of the class.

Verifying that an object instance complies with ABC in Python

I have an API that receives a serialized representation of an object that I expect to comply with a particular interface (known at development time). The serialized data I receive includes details that are used to create implementations of the methods/properties of this interface, so the actual object gets constructed at runtime; however, method names, signatures, property types, etc. are expected to match those known from the interface at development time. I would like to be able to construct this object at runtime, and then verify interface compliance, preferably failing immediately once an invalid object is constructed, not just when I try to invoke a method that's not there.
I am new to Python, so I am not sure if there is an idiomatic way of doing such a check. I have investigated using Abstract Base Classes, and annotating my constructed object with such a class. Using annotations is convenient during development time because I can get intellisense in VSCode, but they are not used to verify that my constructed object implements the ABC correctly at runtime - for example, when it is passed into a method as a parameter, like this:
def my_method(self, generated_object: MyABC):
Is there another approach to doing what I have described (casting/coercing to the ABC, or perhaps using a different language feature)? Or is my best bet to implement my own validator that will compare the methods/properties on the constructed object vs those on the ABC?
import abc
class Base(abc.ABC):
#abc.abstractmethod
def i_require_this(self):
pass
class Concrete(Base):
def __init__(self):
return
concrete = Concrete()
TypeError: Can't instantiate abstract class Concrete with abstract methods i_require_this

can i list methods in python?

What i have is for each instance of a class a different method.So what i want is when i make a new intance of that class to be somehow able to choose which method this instance will call.I am a complete newbie in python and i wonder if i could have a list of methods and each instance to call a specific one from this list.Is that even possible?
I did some search and found the http://docs.python.org/2/library/inspect.html (inspect module) but i got confused.
In python, functions are first class objects. So, you can directly pass a function as argument. If you have defined functions f(x), g(x), h(x), you can create a class method
def set_function(self, external_function):
self.F = external_function
You can then use object.F(x), as if it had been defined inside the class.
However, object belonging to the same class having different methods is bad design. If objects of the same class have different behavior, they should probably belong to different classes to begin with. A better approach would be to subclass the original class, define the different functions inside the subclasses, and then instantiate the corresponding objects.

Python : serialise class hierarchy

I have to serialise a dynamically created class hierarchy. And a bunch of objects - instances of the latter classes.
Python pickle is not of big help, its wiki says "Classes ... cannot be pickled". O there may be some trick that I cannot figure.
Performance requirement:
Deserialization should be pretty fast, because the serialised staff serves for cache and should save me the work of creating the same class hierarchy.
Details:
classes are created dynamically using type and sometimes meta-classes.
If you provide a custom object.__reduce__() method I believe you can still use pickling.
Normally, when pickling, the class import path is stored, plus instance state. On unpickling, the class is imported, and a new instance is created using the stored state. This is why pickling cannot work with dynamic classes, there is nothing to import.
The object.__reduce__() method lets you store a different instance factory. The callable returned by this function is stored (again by import path), and called with specified arguments to produce an instance. This instance is then used to apply state to, in the same way a regular instance would be unpickled:
def class_factory(name):
return globals()[name]()
class SomeDynamicClass(object):
def __reduce__(self):
return (class_factory, (type(self).__name__,), self.__dict__)
Here __reduce__ returns a function, the arguments for the function, and the instance state.
All you need to do then, is provide the right arguments to the factory function to recreate the class, and return an instance of that class. It'll be used instead of importing the class directly.
Classes are normal python objects, so, in theory, should be picklable, if you provide __reduce__ (or implement other pickle protocol methods) for them. Try to define __reduce__ on their metaclass.

What's the best way to extend the functionality of factory-produced classes outside of the module in python?

I've been reading lots of previous SO discussions of factory functions, etc. and still don't know what the best (pythonic) approach is to this particular situation. I'll admit up front that i am imposing a somewhat artificial constraint on the problem in that i want my solution to work without modifying the module i am trying to extend: i could make modifications to it, but let's assume that it must remain as-is because i'm trying to understand best practice in this situation.
I'm working with the http://pypi.python.org/pypi/icalendar module, which handles parsing from and serializing to the Icalendar spec (hereafter ical). It parses the text into a hierarchy of dictionary-like "component" objects, where every "component" is an instance of a trivial derived class implementing the different valid ical types (VCALENDAR, VEVENT, etc.) and they are all spit out by a recursive factory from the common parent class:
class Component(...):
#classmethod
def from_ical(cls, ...)
I have created a 'CalendarFile' class that extends the ical 'Calendar' class, including in it generator function of its own:
class CalendarFile(Calendar):
#classmethod
def from_file(cls, ics):
which opens a file (ics) and passes it on:
instance = cls.from_ical(f.read())
It initializes and modifies some other things in instance and then returns it. The problem is that instance ends up being a Calendar object instead of a CalendarFile object, in spite of cls being CalendarFile. Short of going into the factory function of the ical module and fiddling around in there, is there any way to essentially "recast" that object as a 'CalendarFile'?
The alternatives (again without modifying the original module) that I have considered are:make the CalendarFile class a has-a Calendar class (each instance creates its own internal instance of a Calendar object), but that seems methodically stilted.
fiddle with the returned object to give it the methods it needs (i know there's a term for creating a customized object but it escapes me).
make the additional methods into functions and just have them work with instances of Calendar.
or perhaps the answer is that i shouldn't be trying to subclass from a module in the first place, and this type of code belongs in the module itself.
Again i'm trying to understand what the "best" approach is and also learn if i'm missing any alternatives. Thanks.
Normally, I would expect an alternative constructor defined as a classmethod to simply call the class's standard constructor, transforming the arguments that it receives into valid arguments to the standard constructor.
>>> class Toy(object):
... def __init__(self, x):
... self.x = abs(x)
... def __repr__(self):
... return 'Toy({})'.format(self.x)
... #classmethod
... def from_string(cls, s):
... return cls(int(s))
...
>>> Toy.from_string('5')
Toy(5)
In most cases, I would strongly recommend something like this approach; this is the gold standard for alternative constructors.
But this is a special case.
I've now looked over the source, and I think the best way to add a new class is to edit the module directly; otherwise, scrap inheritance and take option one (your "has-a" option). The different classes are all slightly differentiated versions of the same container class -- they shouldn't really even be separate classes. But if you want to add a new class in the idiom of the code as it it is written, you have to add a new class to the module itself. Furthermore, from_iter is deceptively named; it's not really a constructor at all. I think it should be a standalone function. It builds a whole tree of components linked together, and the code that builds the individual components is buried in a chain of calls to various factory functions that also should be standalone functions but aren't. IMO much of that code ought to live in __init__ where it would be useful to you for subclassing, but it doesn't.
Indeed, none of the subclasses of Component even add any methods. By adding methods to your subclass of Calendar, you're completely disregarding the actual idiom of the code. I don't like its idiom very much but by disregarding that idiom, you're making it even worse. If you don't want to modify the original module, then forget about inheritance here and give your object a has-a relationship to Calendar objects. Don't modify __class__; establish your own OO structure that follows standard OO practices.

Categories