On 2/11/21 1:43 PM, Greg Ewing wrote:
On 12/02/21 7:05 am, Andras Tantos wrote:
a = B()
a.m(41)
a.m = MethodType(method, a)
a.m(42)
Are you sure you really need to inject methods into instances
like this? What problem are you trying to solve by doing so?
There's almost certainly a better way to approach it.
Greg,
This is going to be a long a convoluted story, but since, you've asked...
I'm developing a library to describe hardware (RTL) in Python and
convert it into Verilog (or potentially other languages).
In this project, I have two concepts:
1. Ports, which are the connection points on the various netlist
entities. These would be the inputs and outputs of an AND gate for example
2. NetTypes, which describe the type of data that can travel through a
net (and thus through a Port). One such type would be an 8-bit signed
integer, or a simple logic signal.
There are derived types of the Port object (for inputs and outputs etc.)
as well as of NetType (for signed integers, structs, etc.)
An interesting aspect of the problem is that most ports don't need to
have a type initially: it can be deduced from the connectivity (netlist)
of the circuit described. So, for example the above mentioned AND gate
can handle any input as long as they are of the same NetType and produce
an output of the same NetType. This is to say, that Ports have an
optional NetType, the association between Port and NetType is dynamic
and changes during the lifetime of the Port instance.
There are two ways I can think of modelling this in Python:
1. A (derived) Port instance uses multiple-inheritance to also inherit
from it's (derived) NetType
2. A (derived) Port instance has a member of a (derived) NetType instance
I went with #2 in my current implementation.
Now, when a Port gets assigned a NetType, it needs to gain all sorts of
new features. It for example should have a 'length' attribute that tells
how many bits are needed to represent its possible values. The list of
these new features (attributes, methods, properties) are known to the
NetType and should be injected into the Port when the NetType is
assigned to the Port.
With #1, the situation is different, but not any less complicated: now,
the features are automatically appear in the Port instance (maybe even
too much so) but we dynamically mess with the inheritance tree of the
type of the Port instance.
The example I've written up deals with the problems when I try to inject
these new features into the Port instance (say a new method) and the
method implementation intends to call back the base-class behavior for
some reason.
I believe even #1 could have similar problems in different ways though:
since I manipulate the inheritance chain dynamically, I don't think
there's a guarantee that the statically determined '__class__' cell will
be the same as the dynamically expected one.
Andras
--
https://mail.python.org/mailman/listinfo/python-list