Skip to content

Commit 0ee0d62

Browse files
committed
DOC: Add composition example to internals.rst
1 parent f100ebf commit 0ee0d62

File tree

1 file changed

+73
-2
lines changed

1 file changed

+73
-2
lines changed

doc/source/internals.rst

+73-2
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,79 @@ not check (or care) whether the levels themselves are sorted. Fortunately, the
9494
constructors ``from_tuples`` and ``from_arrays`` ensure that this is true, but
9595
if you compute the levels and labels yourself, please be careful.
9696

97+
.. _ref-composition-pandas:
9798

98-
.. _:
99+
Define Original Data Structures using pandas
100+
--------------------------------------------
101+
102+
.. warning:: If you simply want to add some functionalities to ``pandas``, the easiest
103+
way is monkey-patching. See :ref:`Adding Features to your pandas Installation <ref-monkey-patching>`.
104+
105+
This section describes how to define your original data structure which extends ``pandas`` functionalities using `composition <http://en.wikipedia.org/wiki/Composition_over_inheritance>`_.
106+
107+
Below example shows an original class which is mostly compatible with ``Series``.
108+
The class have a ``_series`` property to hold standard ``Series`` (composition), and defining ``__getattribute__`` to delegate all the undefined properties / methods to it.
109+
110+
.. code-block:: python
111+
112+
class CompositedSeries(object):
113+
114+
def __init__(self, arr, *args, **kwargs):
115+
self._series = Series(arr, *args, **kwargs)
116+
117+
def __getattribute__(self, key):
118+
try:
119+
# try to use its own attributes first
120+
return object.__getattribute__(self, key)
121+
except AttributeError:
122+
# if not found, use Series attribute
123+
return getattr(self._series, key)
124+
125+
def __getitem__(self, key):
126+
# should results in the same class
127+
return CompositedSeries(self._series[key])
128+
129+
def __repr__(self):
130+
return repr(self._series)
131+
132+
def original_method(self):
133+
return 'result'
134+
135+
The class can behave almost the same as standard ``Series``.
136+
Note that some operations (such as arithmetic / set operations) will fail because
137+
these are undefined in above example.
138+
139+
.. code-block:: python
140+
141+
>>> s = CompositedSeries([1, 2, 3], index=['A', 'B', 'C'])
142+
>>> s
143+
A 1
144+
B 2
145+
C 3
146+
dtype: int64
147+
148+
>>> s.dtype
149+
int64
150+
151+
>>> type(s)
152+
<class '__main__.CompositedSeries'>
153+
154+
>>> sliced = s[1:3]
155+
>>> sliced
156+
B 2
157+
C 3
158+
dtype: int64
159+
160+
>>> type(sliced)
161+
<class '__main__.CompositedSeries'>
162+
163+
>>> sliced.original_method()
164+
result
165+
166+
>>> sliced + 2
167+
TypeError: unsupported operand type(s) for +: 'CompositedSeries' and 'int'
168+
169+
.. _ref-subclassing-pandas:
99170
100171
Subclassing pandas Data Structures
101172
----------------------------------
@@ -104,7 +175,7 @@ Subclassing pandas Data Structures
104175
105176
1. Monkey-patching: See :ref:`Adding Features to your pandas Installation <ref-monkey-patching>`.
106177
107-
2. Use *composition*. See `here <http://en.wikipedia.org/wiki/Composition_over_inheritance>`_.
178+
2. Use *composition*. See :ref:`Define Original Data Structures using pandas <ref-composition-pandas>`.
108179
109180
This section describes how to subclass ``pandas`` data structures to meet more specific needs. There are 2 points which need attention:
110181

0 commit comments

Comments
 (0)