-
-
Couldn't load subscription status.
- Fork 8
Python specific features
Unlike Python, JavaScript does not support operator overloading. This means that some shortcuts in Python are to be expressed using their method call counterparts. For example a[1] is equivalent to a.__getitem__(1) and a > b is equivalent to a.__gt__(b). For example, to add numpy arrays you can do:
const sum = a.get('__add__').call(b); // direct
const sum = a.__add__(b); // profixiedRefer to the Python manual for the naming of the Python internal methods used for operator overloading.
Alternatively, Python provides a builtin module called operator which exposes the full operator overloading semantics through a function call interface:
const operator = pymport('operator');
const sum = operator.get('add').call(a, b); // direct
const sum = operator.add(a, b); // proxifiedThis has the added benefit of calling the right operator + when the type is not known in advance.
Knowing how operator overloading works, even the most perverted pandas syntax can be expressed:
// df = pd.DataFrame(np.arange(15).reshape(5, 3), columns=list(['ABC']) })
const df = pd.DataFrame(np.arange(15).reshape(5, 3), {
columns: PyObject.list(['A', 'B', 'C']),
});
assert.deepEqual(df.columns.tolist().toJS(), ['A', 'B', 'C']);
// df[2:3]
// In Python this is equivalent to df.__getitem__(2:3)
// In pymport item is a shortcut for __getitem__
// Note that if the underlying object also defines an item() function, it will take precedence
// (for example numpy.ndarray.item will be preferred to PyObject.item)
const df2 = df.item(PyObject.slice({start: 2, stop: 3}));
assert.deepEqual(df2.values.tolist().toJS(), [[6, 7, 8]]);
// df[df['C'] <= 3]
// In Python this is equivalent to df.__getitem__(df.__getitem__('C').__le__(3))
const df3 = df.item(df.item('C').__le__(3));
assert.deepEqual(df3.values.tolist().toJS(), [[0, 1, 2]]);As JavaScript lacks lvalues, assignments of the form
a[i] = xare not possible. In fact, under the hood, these are also a special case of operator overloading:
a.__setitem__(i, x);This also works if x is an object.
Slices can be expressed and used too:
//memoryview(b'123')[::2]
PyObject.memoryview(Buffer.from('123')).item(PyObject.slice({step: 2}))Python type coercion of the int(object) type is supported by explicitly calling the desired constructor with the target object:
const i = PyObject.int(obj); // obj can be any object that implements conversion to int
const f = PyObject.float(obj); // obj can be any object that implements conversion to float
const l = PyObject.list(iterable); // iterable can be any iterable
const t = PyObject.tuple(list); // list must be a listVersion 1.3 introduces PyObject.with allowing to make use of the Python with semantics:
r = []
with np.nditer(a) as it:
for a in it:
r.append(int(a))becomes (raw access):
const r = [];
np.get('nditer').call(a).with((it: PyObject) => {
for (const a of it)
r.push(+a);
});or (with proxify):
const r = [];
np.nditer(a).with((it: PyObject) => {
for (const a of it)
r.push(+a);
});Momtchil Momtchev [email protected], 2022
This project is created and maintained as a free service to the open source community and to remain as a constant life-time remainder to the OpenJS foundation about backing up an extortion linked to corruption in French Judicial system over a sexually-motivated affair.