diff --git a/python_binding/operator/pybind_Add.cpp b/python_binding/operator/pybind_Add.cpp
index 1f588352d46e19cb5f40fc98d5f94ebd1f392dcc..103e7c1e4db6e197a1dac959a25d266e031d3e55 100644
--- a/python_binding/operator/pybind_Add.cpp
+++ b/python_binding/operator/pybind_Add.cpp
@@ -9,11 +9,11 @@
  *
  ********************************************************************************/
 
+#include <memory>
+
 #include <pybind11/pybind11.h>
 
 #include "aidge/operator/Add.hpp"
-#include "aidge/data/Tensor.hpp"
-#include "aidge/backend/OperatorImpl.hpp"
 #include "aidge/operator/OperatorTensor.hpp"
 #include "aidge/utils/Types.h"
 
@@ -22,13 +22,17 @@ namespace Aidge {
 
 void declare_Add(py::module &m) {
   py::class_<Add_Op, std::shared_ptr<Add_Op>, OperatorTensor>(m, "AddOp", py::multiple_inheritance())
-  .def_static("get_inputs_name", &Add_Op::getInputsName)
-  .def_static("get_outputs_name", &Add_Op::getOutputsName);
+    .def(py::init<const IOIndex_t>(), py::arg("nb_inputs"))
+    .def_static("get_inputs_name", &Add_Op::getInputsName)
+    .def_static("get_outputs_name", &Add_Op::getOutputsName);
+
   declare_registrable<Add_Op>(m, "AddOp");
-  m.def("Add", &Add, py::arg("nbIn"), py::arg("name") = "");
+
+  m.def("Add", &Add, py::arg("nb_inputs"), py::arg("name") = "");
 }
 
 void init_Add(py::module &m) {
   declare_Add(m);
 }
+
 } // namespace Aidge
diff --git a/python_binding/operator/pybind_AvgPooling.cpp b/python_binding/operator/pybind_AvgPooling.cpp
index 5d72a3507c4926412b48cda42b1c3bcbe10e9460..966def88033dee8cd6cee06d80dc32114050b430 100644
--- a/python_binding/operator/pybind_AvgPooling.cpp
+++ b/python_binding/operator/pybind_AvgPooling.cpp
@@ -28,16 +28,18 @@ namespace Aidge {
 template <DimIdx_t DIM> void declare_AvgPoolingOp(py::module &m) {
   const std::string pyClassName("AvgPoolingOp" + std::to_string(DIM) + "D");
   py::class_<AvgPooling_Op<DIM>, std::shared_ptr<AvgPooling_Op<DIM>>, Attributes, OperatorTensor>(
-    m, pyClassName.c_str(),
-    py::multiple_inheritance())
-  .def(py::init<const std::array<DimSize_t, DIM> &,
-                const std::array<DimSize_t, DIM> &>(),
-        py::arg("kernel_dims"),
-        py::arg("stride_dims"))
-  .def("get_inputs_name", &AvgPooling_Op<DIM>::getInputsName)
-  .def("get_outputs_name", &AvgPooling_Op<DIM>::getOutputsName)
-  .def("attributes_name", &AvgPooling_Op<DIM>::staticGetAttrsName);
+        m, pyClassName.c_str(),
+        py::multiple_inheritance())
+    .def(py::init<const std::array<DimSize_t, DIM> &,
+                  const std::array<DimSize_t, DIM> &>(),
+            py::arg("kernel_dims"),
+            py::arg("stride_dims"))
+    .def("get_inputs_name", &AvgPooling_Op<DIM>::getInputsName)
+    .def("get_outputs_name", &AvgPooling_Op<DIM>::getOutputsName)
+    .def("attributes_name", &AvgPooling_Op<DIM>::staticGetAttrsName);
+
   declare_registrable<AvgPooling_Op<DIM>>(m, pyClassName);
+
   m.def(("AvgPooling" + std::to_string(DIM) + "D").c_str(), [](const std::vector<DimSize_t>& kernel_dims,
                                                                   const std::string& name,
                                                                   const std::vector<DimSize_t> &stride_dims) {
@@ -48,7 +50,6 @@ template <DimIdx_t DIM> void declare_AvgPoolingOp(py::module &m) {
     }, py::arg("kernel_dims"),
        py::arg("name") = "",
        py::arg("stride_dims") = std::vector<DimSize_t>(DIM,1));
-
 }
 
 
@@ -61,4 +62,5 @@ void init_AvgPooling(py::module &m) {
   // m.def("AvgPooling1D", static_cast<NodeAPI(*)(const char*, int, int, int const
   // (&)[1])>(&AvgPooling));
 }
+
 } // namespace Aidge
diff --git a/python_binding/operator/pybind_BatchNorm.cpp b/python_binding/operator/pybind_BatchNorm.cpp
index a12df1c8656003aef6c643b1060f21cc44111197..4ec25e02a50330bdf764b598b598836a251d65ea 100644
--- a/python_binding/operator/pybind_BatchNorm.cpp
+++ b/python_binding/operator/pybind_BatchNorm.cpp
@@ -24,18 +24,20 @@ template <DimSize_t DIM>
 void declare_BatchNormOp(py::module& m) {
     const std::string pyClassName("BatchNormOp" + std::to_string(DIM) + "D");
     py::class_<BatchNorm_Op<DIM>, std::shared_ptr<BatchNorm_Op<DIM>>, Attributes, OperatorTensor>(m, pyClassName.c_str(), py::multiple_inheritance())
-    .def(py::init<float, float>(),
-        py::arg("epsilon"),
-        py::arg("momentum"))
-    .def_static("get_inputs_name", &BatchNorm_Op<DIM>::getInputsName)
-    .def_static("get_outputs_name", &BatchNorm_Op<DIM>::getOutputsName)
-    .def_static("attributes_name", &BatchNorm_Op<DIM>::staticGetAttrsName);
+        .def(py::init<float, float>(),
+            py::arg("epsilon"),
+            py::arg("momentum"))
+        .def_static("get_inputs_name", &BatchNorm_Op<DIM>::getInputsName)
+        .def_static("get_outputs_name", &BatchNorm_Op<DIM>::getOutputsName)
+        .def_static("attributes_name", &BatchNorm_Op<DIM>::staticGetAttrsName);
+
     declare_registrable<BatchNorm_Op<DIM>>(m, pyClassName);
 
-    m.def(("BatchNorm" + std::to_string(DIM) + "D").c_str(), &BatchNorm<DIM>, py::arg("nbFeatures"), py::arg("epsilon") = 1.0e-5F, py::arg("momentum") = 0.1F, py::arg("name") = "");
+    m.def(("BatchNorm" + std::to_string(DIM) + "D").c_str(), &BatchNorm<DIM>, py::arg("nb_features"), py::arg("epsilon") = 1.0e-5F, py::arg("momentum") = 0.1F, py::arg("name") = "");
 }
 
 void init_BatchNorm(py::module &m) {
     declare_BatchNormOp<2>(m);
 }
+
 }  // namespace Aidge
diff --git a/python_binding/operator/pybind_Concat.cpp b/python_binding/operator/pybind_Concat.cpp
index b08554a36c1bb955e36764c0147e0119a53d46e7..07bb9f2fc16fcbefb693aeec00c380661f4a6e44 100644
--- a/python_binding/operator/pybind_Concat.cpp
+++ b/python_binding/operator/pybind_Concat.cpp
@@ -21,11 +21,16 @@ namespace Aidge {
 
 void init_Concat(py::module& m) {
     py::class_<Concat_Op, std::shared_ptr<Concat_Op>, Attributes, OperatorTensor>(m, "ConcatOp", py::multiple_inheritance())
-    .def_static("get_inputs_name", &Concat_Op::getInputsName)
-    .def_static("get_outputs_name", &Concat_Op::getOutputsName)
-    .def_static("attributes_name", &Concat_Op::staticGetAttrsName);
+        .def(py::init<const IOIndex_t, const DimSize_t>(),
+                py::arg("nb_inputs"),
+                py::arg("axis"))
+        .def_static("get_inputs_name", &Concat_Op::getInputsName)
+        .def_static("get_outputs_name", &Concat_Op::getOutputsName)
+        .def_static("attributes_name", &Concat_Op::staticGetAttrsName);
 
     declare_registrable<Concat_Op>(m, "ConcatOp");
-    m.def("Concat", &Concat, py::arg("nbIn"), py::arg("axis"), py::arg("name") = "");
+
+    m.def("Concat", &Concat, py::arg("nb_inputs"), py::arg("axis"), py::arg("name") = "");
 }
+
 }  // namespace Aidge
diff --git a/python_binding/operator/pybind_Div.cpp b/python_binding/operator/pybind_Div.cpp
index 2f7dbac6317f107976b9de72463a9c794c8edaf4..9dcb98a54596f32525d2880dd6e955d4643f6e7c 100644
--- a/python_binding/operator/pybind_Div.cpp
+++ b/python_binding/operator/pybind_Div.cpp
@@ -20,9 +20,11 @@ namespace Aidge {
 
 void init_Div(py::module& m) {
     py::class_<Div_Op, std::shared_ptr<Div_Op>, OperatorTensor>(m, "DivOp", py::multiple_inheritance())
-    .def_static("get_inputs_name", &Div_Op::getInputsName)
-    .def_static("get_outputs_name", &Div_Op::getOutputsName);
+        .def(py::init<>())
+        .def_static("get_inputs_name", &Div_Op::getInputsName)
+        .def_static("get_outputs_name", &Div_Op::getOutputsName);
     declare_registrable<Div_Op>(m, "DivOp");
     m.def("Div", &Div, py::arg("name") = "");
 }
+
 }  // namespace Aidge
diff --git a/python_binding/operator/pybind_Erf.cpp b/python_binding/operator/pybind_Erf.cpp
index 4979ce54f72c12ff564d10ebf6fbd38aaec81e92..c248753ca8de46293d49ce4dc614ae258c313256 100644
--- a/python_binding/operator/pybind_Erf.cpp
+++ b/python_binding/operator/pybind_Erf.cpp
@@ -20,9 +20,12 @@ namespace Aidge {
 
 void init_Erf(py::module& m) {
     py::class_<Erf_Op, std::shared_ptr<Erf_Op>, OperatorTensor>(m, "ErfOp", py::multiple_inheritance())
-    .def_static("get_inputs_name", &Erf_Op::getInputsName)
-    .def_static("get_outputs_name", &Erf_Op::getOutputsName);
+        .def(py::init<>())
+        .def_static("get_inputs_name", &Erf_Op::getInputsName)
+        .def_static("get_outputs_name", &Erf_Op::getOutputsName);
+
     declare_registrable<Erf_Op>(m, "ErfOp");
+
     m.def("Erf", &Erf, py::arg("name") = "");
 }
 }  // namespace Aidge
diff --git a/python_binding/operator/pybind_FC.cpp b/python_binding/operator/pybind_FC.cpp
index 185df9220bf112d729431b497b9c49af8997b7b8..989f88d1e62d354004da9c2d81a6006f90e47a9d 100644
--- a/python_binding/operator/pybind_FC.cpp
+++ b/python_binding/operator/pybind_FC.cpp
@@ -22,14 +22,18 @@ namespace Aidge {
 
 void declare_FC(py::module &m) {
   py::class_<FC_Op, std::shared_ptr<FC_Op>, Attributes, OperatorTensor>(m, "FCOp", py::multiple_inheritance())
-  .def_static("get_inputs_name", &FC_Op::getInputsName)
-  .def_static("get_outputs_name", &FC_Op::getOutputsName)
-  .def_static("attributes_name", &FC_Op::staticGetAttrsName);
+    .def(py::init<bool>(), py::arg("no_bias"))
+    .def_static("get_inputs_name", &FC_Op::getInputsName)
+    .def_static("get_outputs_name", &FC_Op::getOutputsName)
+    .def_static("attributes_name", &FC_Op::staticGetAttrsName);
+
   declare_registrable<FC_Op>(m, "FCOp");
-  m.def("FC", &FC, py::arg("in_channels"), py::arg("out_channels"), py::arg("nobias") = false, py::arg("name") = "");
+
+  m.def("FC", &FC, py::arg("in_channels"), py::arg("out_channels"), py::arg("no_bias") = false, py::arg("name") = "");
 }
 
 void init_FC(py::module &m) {
   declare_FC(m);
 }
+
 } // namespace Aidge
diff --git a/python_binding/operator/pybind_Gather.cpp b/python_binding/operator/pybind_Gather.cpp
index 2c6d5f3cf0af893c12e31659f30f1059c52c3a26..83891624deede4b1f6f6f0c649358e9ed8de0a24 100644
--- a/python_binding/operator/pybind_Gather.cpp
+++ b/python_binding/operator/pybind_Gather.cpp
@@ -22,11 +22,19 @@ namespace Aidge {
 
 void init_Gather(py::module& m) {
     py::class_<Gather_Op, std::shared_ptr<Gather_Op>, Attributes, OperatorTensor>(m, "GatherOp", py::multiple_inheritance())
-    .def_static("get_inputs_name", &Gather_Op::getInputsName)
-    .def_static("get_outputs_name", &Gather_Op::getOutputsName)
-    .def_static("attributes_name", &Gather_Op::staticGetAttrsName);
+        .def(py::init<std::int8_t,
+                      const std::vector<int64_t>,
+                      const std::vector<DimSize_t>>(),
+                py::arg("axis"),
+                py::arg("indices"),
+                py::arg("gathered_shape"))
+        .def_static("get_inputs_name", &Gather_Op::getInputsName)
+        .def_static("get_outputs_name", &Gather_Op::getOutputsName)
+        .def_static("attributes_name", &Gather_Op::staticGetAttrsName);
+
     declare_registrable<Gather_Op>(m, "GatherOp");
 
     m.def("Gather", &Gather, py::arg("axis") = 0, py::arg("indices") = std::vector<std::int64_t>(), py::arg("gathered_shape") = std::vector<std::size_t>(), py::arg("name") = "");
 }
+
 }  // namespace Aidge
diff --git a/python_binding/operator/pybind_GenericOperator.cpp b/python_binding/operator/pybind_GenericOperator.cpp
index 897cd359a4b368dc599f37136ade3508b5ec5a76..7078ca3b0e84d7251aadbc6035e348ac9cd72571 100644
--- a/python_binding/operator/pybind_GenericOperator.cpp
+++ b/python_binding/operator/pybind_GenericOperator.cpp
@@ -9,23 +9,33 @@
  *
  ********************************************************************************/
 
+#include <stdio.h>
+
+#include <string>
+
+#include <pybind11/functional.h>
 #include <pybind11/pybind11.h>
 #include <pybind11/stl.h>
-#include <pybind11/functional.h>
-#include <stdio.h>
 
 #include "aidge/backend/OperatorImpl.hpp"
 #include "aidge/data/Tensor.hpp"
 #include "aidge/operator/GenericOperator.hpp"
 #include "aidge/operator/OperatorTensor.hpp"
+#include "aidge/utils/Types.h"
+
 namespace py = pybind11;
 namespace Aidge {
 
 void init_GenericOperator(py::module& m) {
     py::class_<GenericOperator_Op, std::shared_ptr<GenericOperator_Op>, DynamicAttributes, OperatorTensor>(m, "GenericOperatorOp",
                                                                                   py::multiple_inheritance())
-    .def_readonly_static("identity", &GenericOperator_Op::Identity)
-    .def("set_forward_dims", &GenericOperator_Op::setForwardDims, py::arg("computation_function"));
+        .def(py::init<const std::string&, IOIndex_t, IOIndex_t, IOIndex_t>(),
+                py::arg("type"),
+                py::arg("nb_data"),
+                py::arg("nb_param"),
+                py::arg("nb_outputs"))
+        .def_readonly_static("identity", &GenericOperator_Op::Identity)
+        .def("set_forward_dims", &GenericOperator_Op::setForwardDims, py::arg("computation_function"));
 
     // &GenericOperator
     m.def("GenericOperator",
diff --git a/python_binding/operator/pybind_GlobalAveragePooling.cpp b/python_binding/operator/pybind_GlobalAveragePooling.cpp
index b5f19894618fa5ee14fdc346f0b59cc87814a724..d4d2a921addaef676913cee2a16991ad36686767 100644
--- a/python_binding/operator/pybind_GlobalAveragePooling.cpp
+++ b/python_binding/operator/pybind_GlobalAveragePooling.cpp
@@ -23,9 +23,13 @@ void init_GlobalAveragePooling(py::module &m) {
   py::class_<GlobalAveragePooling_Op, std::shared_ptr<GlobalAveragePooling_Op>,
              OperatorTensor>(m, pyClassName.c_str(),
                              py::multiple_inheritance())
+      .def(py::init<>())
       .def_static("get_inputs_name", &GlobalAveragePooling_Op::getInputsName)
       .def_static("get_outputs_name", &GlobalAveragePooling_Op::getOutputsName);
+
   declare_registrable<GlobalAveragePooling_Op>(m, pyClassName);
+
   m.def("globalaveragepooling", &GlobalAveragePooling, py::arg("name") = "");
 }
+
 } // namespace Aidge
diff --git a/python_binding/operator/pybind_Identity.cpp b/python_binding/operator/pybind_Identity.cpp
index 1ab87309358ee700182db1e7c39009cf56c45c7d..560f2889f20233ef928557aa230e6dab7f0a5d2b 100644
--- a/python_binding/operator/pybind_Identity.cpp
+++ b/python_binding/operator/pybind_Identity.cpp
@@ -19,10 +19,12 @@ namespace py = pybind11;
 namespace Aidge {
 
 void init_Identity(py::module& m) {
-    py::class_<Identity_Op, std::shared_ptr<Identity_Op>, Operator>(m, "IdentityOp", py::multiple_inheritance())
-    .def_static("get_inputs_name", &Identity_Op::getInputsName)
-    .def_static("get_outputs_name", &Identity_Op::getOutputsName);
+    py::class_<Identity_Op, std::shared_ptr<Identity_Op>, OperatorTensor>(m, "IdentityOp", py::multiple_inheritance())
+        .def(py::init<>())
+        .def_static("get_inputs_name", &Identity_Op::getInputsName)
+        .def_static("get_outputs_name", &Identity_Op::getOutputsName);
 
     m.def("Identity", &Identity, py::arg("name") = "");
 }
+
 }  // namespace Aidge
diff --git a/python_binding/operator/pybind_LeakyReLU.cpp b/python_binding/operator/pybind_LeakyReLU.cpp
index 4fbef4b0dcd3b4c7128d36d1aee09225d5996b7c..b859b3be5b3dd2606d227a3ca26bd1b4eb8e75a9 100644
--- a/python_binding/operator/pybind_LeakyReLU.cpp
+++ b/python_binding/operator/pybind_LeakyReLU.cpp
@@ -20,10 +20,12 @@ namespace Aidge {
 
 void init_LeakyReLU(py::module& m) {
     py::class_<LeakyReLU_Op, std::shared_ptr<LeakyReLU_Op>, Attributes, OperatorTensor>(m, "LeakyReLUOp", py::multiple_inheritance())
-    .def_static("get_inputs_name", &LeakyReLU_Op::getInputsName)
-    .def_static("get_outputs_name", &LeakyReLU_Op::getOutputsName)
-    .def_static("attributes_name", &LeakyReLU_Op::staticGetAttrsName);
+        .def(py::init<float>(), py::arg("negative_slope"))
+        .def_static("get_inputs_name", &LeakyReLU_Op::getInputsName)
+        .def_static("get_outputs_name", &LeakyReLU_Op::getOutputsName)
+        .def_static("attributes_name", &LeakyReLU_Op::staticGetAttrsName);
     declare_registrable<LeakyReLU_Op>(m, "LeakyReLUOp");
     m.def("LeakyReLU", &LeakyReLU, py::arg("negative_slope") = 0.0f, py::arg("name") = "");
 }
+
 }  // namespace Aidge
diff --git a/python_binding/operator/pybind_Matmul.cpp b/python_binding/operator/pybind_Matmul.cpp
index f56da5a2457f249efbce84d246a6e204d3d2ecd7..09e11f89ea579b5a3aa75f177958d981c53f1dce 100644
--- a/python_binding/operator/pybind_Matmul.cpp
+++ b/python_binding/operator/pybind_Matmul.cpp
@@ -22,8 +22,9 @@ namespace Aidge {
 
 void init_MatMul(py::module &m) {
   py::class_<MatMul_Op, std::shared_ptr<MatMul_Op>, OperatorTensor>(m, "MatMulOp", py::multiple_inheritance())
-  .def_static("get_inputs_name", &MatMul_Op::getInputsName)
-  .def_static("get_outputs_name", &MatMul_Op::getOutputsName);
+    .def(py::init<>())
+    .def_static("get_inputs_name", &MatMul_Op::getInputsName)
+    .def_static("get_outputs_name", &MatMul_Op::getOutputsName);
   declare_registrable<MatMul_Op>(m, "MatMulOp");
   m.def("MatMul", &MatMul, py::arg("name") = "");
 }
diff --git a/python_binding/operator/pybind_MetaOperatorDefs.cpp b/python_binding/operator/pybind_MetaOperatorDefs.cpp
index 20cd3f156996c98bb64502a90ab98535f87cc2a3..ee3f85b6578054512df7b0087d1a972176cd50a3 100644
--- a/python_binding/operator/pybind_MetaOperatorDefs.cpp
+++ b/python_binding/operator/pybind_MetaOperatorDefs.cpp
@@ -47,6 +47,24 @@ template <DimIdx_t DIM> void declare_PaddedConvOp(py::module &m) {
        py::arg("padding_dims") = std::vector<DimSize_t>(2*DIM,0),
        py::arg("dilation_dims") = std::vector<DimSize_t>(DIM,1),
        py::arg("no_bias")= false);
+    m.def(("PaddedConvOp" + std::to_string(DIM) + "D").c_str(), [](
+                                                         const std::vector<DimSize_t>& kernel_dims,
+                                                         const std::vector<DimSize_t> &stride_dims,
+                                                         const std::vector<DimSize_t> &padding_dims,
+                                                         const std::vector<DimSize_t> &dilation_dims,
+                                                         bool no_bias)
+    {
+        AIDGE_ASSERT(kernel_dims.size() == DIM, "kernel_dims size [{}] does not match DIM [{}]", kernel_dims.size(), DIM);
+        AIDGE_ASSERT(stride_dims.size() == DIM, "stride_dims size [{}] does not match DIM [{}]", stride_dims.size(), DIM);
+        AIDGE_ASSERT(padding_dims.size() == 2*DIM, "padding_dims size [{}] does not match DIM [{}]", padding_dims.size(), 2*DIM);
+        AIDGE_ASSERT(dilation_dims.size() == DIM, "dilation_dims size [{}] does not match DIM [{}]", dilation_dims.size(), DIM);
+
+        return PaddedConv_Op<DIM>(to_array<DIM>(kernel_dims.begin()), to_array<DIM>(stride_dims.begin()), to_array<2*DIM>(padding_dims.begin()), to_array<DIM>(dilation_dims.begin()), no_bias);
+    }, py::arg("kernel_dims"),
+       py::arg("stride_dims") = std::vector<DimSize_t>(DIM,1),
+       py::arg("padding_dims") = std::vector<DimSize_t>(2*DIM,0),
+       py::arg("dilation_dims") = std::vector<DimSize_t>(DIM,1),
+       py::arg("no_bias")= false);
 }
 
 template <DimIdx_t DIM> void declare_PaddedConvDepthWiseOp(py::module &m) {
@@ -71,6 +89,24 @@ template <DimIdx_t DIM> void declare_PaddedConvDepthWiseOp(py::module &m) {
        py::arg("padding_dims") = std::vector<DimSize_t>(2*DIM,0),
        py::arg("dilation_dims") = std::vector<DimSize_t>(DIM,1),
        py::arg("no_bias") = false);
+  m.def(("PaddedConvDepthWiseOp" + std::to_string(DIM) + "D").c_str(), [](
+                                                         const std::vector<DimSize_t>& kernel_dims,
+                                                         const std::vector<DimSize_t> &stride_dims,
+                                                         const std::vector<DimSize_t> &padding_dims,
+                                                         const std::vector<DimSize_t> &dilation_dims,
+                                                         bool no_bias)
+    {
+        AIDGE_ASSERT(kernel_dims.size() == DIM, "kernel_dims size [{}] does not match DIM [{}]", kernel_dims.size(), DIM);
+        AIDGE_ASSERT(stride_dims.size() == DIM, "stride_dims size [{}] does not match DIM [{}]", stride_dims.size(), DIM);
+        AIDGE_ASSERT(padding_dims.size() == 2*DIM, "padding_dims size [{}] does not match DIM [{}]", padding_dims.size(), 2*DIM);
+        AIDGE_ASSERT(dilation_dims.size() == DIM, "dilation_dims size [{}] does not match DIM [{}]", dilation_dims.size(), DIM);
+
+        return PaddedConvDepthWise_Op<DIM>(to_array<DIM>(kernel_dims.begin()), to_array<DIM>(stride_dims.begin()), to_array<2*DIM>(padding_dims.begin()), to_array<DIM>(dilation_dims.begin()), no_bias);
+    }, py::arg("kernel_dims"),
+       py::arg("stride_dims") = std::vector<DimSize_t>(DIM,1),
+       py::arg("padding_dims") = std::vector<DimSize_t>(2*DIM,0),
+       py::arg("dilation_dims") = std::vector<DimSize_t>(DIM,1),
+       py::arg("no_bias") = false);
 
 }
 
@@ -89,7 +125,18 @@ template <DimIdx_t DIM> void declare_PaddedAvgPoolingOp(py::module &m) {
        py::arg("name") = "",
        py::arg("stride_dims") = std::vector<DimSize_t>(DIM,1),
        py::arg("padding_dims") = std::vector<DimSize_t>(2*DIM,0));
+  m.def(("PaddedAvgPoolingOp" + std::to_string(DIM) + "D").c_str(), [](const std::vector<DimSize_t>& kernel_dims,
+                                                         const std::vector<DimSize_t> &stride_dims,
+                                                         const std::vector<DimSize_t> &padding_dims)
+    {
+        AIDGE_ASSERT(kernel_dims.size() == DIM, "kernel_dims size [{}] does not match DIM [{}]", kernel_dims.size(), DIM);
+        AIDGE_ASSERT(stride_dims.size() == DIM, "stride_dims size [{}] does not match DIM [{}]", stride_dims.size(), DIM);
+        AIDGE_ASSERT(padding_dims.size() == 2*DIM, "padding_dims size [{}] does not match DIM [{}]", padding_dims.size(), 2*DIM);
 
+        return PaddedAvgPooling_Op<DIM>(to_array<DIM>(kernel_dims.begin()), to_array<DIM>(stride_dims.begin()), to_array<2*DIM>(padding_dims.begin()));
+    }, py::arg("kernel_dims"),
+       py::arg("stride_dims") = std::vector<DimSize_t>(DIM,1),
+       py::arg("padding_dims") = std::vector<DimSize_t>(2*DIM,0));
 }
 
 template <DimIdx_t DIM> void declare_PaddedMaxPoolingOp(py::module &m) {
@@ -109,6 +156,20 @@ template <DimIdx_t DIM> void declare_PaddedMaxPoolingOp(py::module &m) {
        py::arg("stride_dims") = std::vector<DimSize_t>(DIM,1),
        py::arg("padding_dims") = std::vector<DimSize_t>(2*DIM,0),
        py::arg("ceil_mode") = false);
+  m.def(("PaddedMaxPoolingOp" + std::to_string(DIM) + "D").c_str(), [](const std::vector<DimSize_t>& kernel_dims,
+                                                         const std::vector<DimSize_t> &stride_dims,
+                                                         const std::vector<DimSize_t> &padding_dims,
+                                                         bool ceil_mode)
+    {
+        AIDGE_ASSERT(kernel_dims.size() == DIM, "kernel_dims size [{}] does not match DIM [{}]", kernel_dims.size(), DIM);
+        AIDGE_ASSERT(stride_dims.size() == DIM, "stride_dims size [{}] does not match DIM [{}]", stride_dims.size(), DIM);
+        AIDGE_ASSERT(padding_dims.size() == 2*DIM, "padding_dims size [{}] does not match DIM [{}]", padding_dims.size(), 2*DIM);
+
+        return PaddedMaxPooling_Op<DIM>(to_array<DIM>(kernel_dims.begin()), to_array<DIM>(stride_dims.begin()), to_array<2*DIM>(padding_dims.begin()), ceil_mode);
+    }, py::arg("kernel_dims"),
+       py::arg("stride_dims") = std::vector<DimSize_t>(DIM,1),
+       py::arg("padding_dims") = std::vector<DimSize_t>(2*DIM,0),
+       py::arg("ceil_mode") = false);
 
 }
 
@@ -118,21 +179,24 @@ void declare_LSTMOp(py::module &m) {
        py::arg("seq_length"),
        py::arg("nobias") = false,
        py::arg("name") = "");
+  m.def("LSTMOp", &LSTM_Op,
+       py::arg("seq_length"),
+       py::arg("nobias") = false);
 }
 
 void init_MetaOperatorDefs(py::module &m) {
-  declare_PaddedConvOp<1>(m);
+//   declare_PaddedConvOp<1>(m);
   declare_PaddedConvOp<2>(m);
-  declare_PaddedConvOp<3>(m);
-  declare_PaddedConvDepthWiseOp<1>(m);
+//   declare_PaddedConvOp<3>(m);
+//   declare_PaddedConvDepthWiseOp<1>(m);
   declare_PaddedConvDepthWiseOp<2>(m);
-  declare_PaddedConvDepthWiseOp<3>(m);
-  declare_PaddedAvgPoolingOp<1>(m);
+//   declare_PaddedConvDepthWiseOp<3>(m);
+//   declare_PaddedAvgPoolingOp<1>(m);
   declare_PaddedAvgPoolingOp<2>(m);
-  declare_PaddedAvgPoolingOp<3>(m);
-  declare_PaddedMaxPoolingOp<1>(m);
+//   declare_PaddedAvgPoolingOp<3>(m);
+//   declare_PaddedMaxPoolingOp<1>(m);
   declare_PaddedMaxPoolingOp<2>(m);
-  declare_PaddedMaxPoolingOp<3>(m);
+//   declare_PaddedMaxPoolingOp<3>(m);
   declare_LSTMOp(m);
 
   py::class_<MetaOperator_Op, std::shared_ptr<MetaOperator_Op>, OperatorTensor>(m, "MetaOperator_Op", py::multiple_inheritance())
diff --git a/python_binding/operator/pybind_Mul.cpp b/python_binding/operator/pybind_Mul.cpp
index 60f8ea7012cbf322ff34685da875065c22b44ee0..1658b0d959c0882d53e078f6d68b4474b34c739e 100644
--- a/python_binding/operator/pybind_Mul.cpp
+++ b/python_binding/operator/pybind_Mul.cpp
@@ -20,6 +20,7 @@ namespace Aidge {
 
 void init_Mul(py::module& m) {
     py::class_<Mul_Op, std::shared_ptr<Mul_Op>, OperatorTensor>(m, "MulOp", py::multiple_inheritance())
+    .def(py::init<>())
     .def_static("get_inputs_name", &Mul_Op::getInputsName)
     .def_static("get_outputs_name", &Mul_Op::getOutputsName);
     declare_registrable<Mul_Op>(m, "MulOp");
diff --git a/python_binding/operator/pybind_Pop.cpp b/python_binding/operator/pybind_Pop.cpp
index 333e55b3daa9b661995756507e60d610a8ac84a0..d8873636d029435706cfb9766262ae0b8409d8a5 100644
--- a/python_binding/operator/pybind_Pop.cpp
+++ b/python_binding/operator/pybind_Pop.cpp
@@ -20,6 +20,7 @@ namespace Aidge {
 
 void init_Pop(py::module& m) {
     py::class_<Pop_Op, std::shared_ptr<Pop_Op>, OperatorTensor, Attributes>(m, "PopOp", py::multiple_inheritance())
+    .def(py::init<>())
     .def_static("get_inputs_name", &Pop_Op::getInputsName)
     .def_static("get_outputs_name", &Pop_Op::getOutputsName);
 
diff --git a/python_binding/operator/pybind_Pow.cpp b/python_binding/operator/pybind_Pow.cpp
index c88e699413b99ff93772fc44d867d32717767155..e5d67542cd1acc5b2982081e4cf3a91948542147 100644
--- a/python_binding/operator/pybind_Pow.cpp
+++ b/python_binding/operator/pybind_Pow.cpp
@@ -20,6 +20,7 @@ namespace Aidge {
 
 void init_Pow(py::module& m) {
     py::class_<Pow_Op, std::shared_ptr<Pow_Op>, OperatorTensor>(m, "PowOp", py::multiple_inheritance())
+    .def(py::init<>())
     .def_static("get_inputs_name", &Pow_Op::getInputsName)
     .def_static("get_outputs_name", &Pow_Op::getOutputsName);
     declare_registrable<Pow_Op>(m, "PowOp");
diff --git a/python_binding/operator/pybind_Producer.cpp b/python_binding/operator/pybind_Producer.cpp
index f1a60f4b20987c4ef489feff2e43a9c6f03916c9..71347554fdc9cd937b1f14df16e370db2f77a267 100644
--- a/python_binding/operator/pybind_Producer.cpp
+++ b/python_binding/operator/pybind_Producer.cpp
@@ -35,12 +35,22 @@ void init_Producer(py::module &m) {
         m,
         "ProducerOp",
         py::multiple_inheritance())
+    .def(py::init<const std::shared_ptr<Tensor>, bool>(), py::arg("tensor"), py::arg("constant"))
     .def("dims", &Producer_Op::dims)
     .def_static("get_inputs_name", &Producer_Op::getInputsName)
     .def_static("get_outputs_name", &Producer_Op::getOutputsName)
     .def_static("attributes_name", &Producer_Op::staticGetAttrsName);
-    m.def("Producer", static_cast<std::shared_ptr<Node>(*)(const std::shared_ptr<Tensor>, const std::string&, bool)>(&Producer), py::arg("tensor"), py::arg("name") = "", py::arg("constant") = false);
+
+    m.def("Producer", static_cast<std::shared_ptr<Node>(*)(
+                                        const std::shared_ptr<Tensor>,
+                                        const std::string&,
+                                        bool)>(&Producer),
+                      py::arg("tensor"),
+                      py::arg("name") = "",
+                      py::arg("constant") = false);
+
     declare_registrable<Producer_Op>(m, "ProducerOp");
+
     declare_Producer<1>(m);
     declare_Producer<2>(m);
     declare_Producer<3>(m);
diff --git a/python_binding/operator/pybind_ReLU.cpp b/python_binding/operator/pybind_ReLU.cpp
index ec8f43b69c189204ae30503ea77dc17ab845c135..d611523f15a7007b0e9ab9cce323ed9a57d8ecdf 100644
--- a/python_binding/operator/pybind_ReLU.cpp
+++ b/python_binding/operator/pybind_ReLU.cpp
@@ -20,6 +20,7 @@ namespace Aidge {
 
 void init_ReLU(py::module& m) {
     py::class_<ReLU_Op, std::shared_ptr<ReLU_Op>, OperatorTensor>(m, "ReLUOp", py::multiple_inheritance())
+    .def(py::init<>())
     .def_static("get_inputs_name", &ReLU_Op::getInputsName)
     .def_static("get_outputs_name", &ReLU_Op::getOutputsName);
     declare_registrable<ReLU_Op>(m, "ReLUOp");
diff --git a/python_binding/operator/pybind_ReduceMean.cpp b/python_binding/operator/pybind_ReduceMean.cpp
index 150d06419845a0ddfa6fec3da904eae94dcd5b19..00201c9bdf4ecd7ad76202c2fe78180317b736dd 100644
--- a/python_binding/operator/pybind_ReduceMean.cpp
+++ b/python_binding/operator/pybind_ReduceMean.cpp
@@ -28,6 +28,7 @@ void declare_ReduceMeanOp(py::module &m) {
   const std::string pyClassName("ReduceMeanOp");
   py::class_<ReduceMean_Op, std::shared_ptr<ReduceMean_Op>, Attributes, OperatorTensor>(
     m, pyClassName.c_str(), py::multiple_inheritance())
+    .def(py::init<std::vector<std::int32_t>, DimSize_t>(), py::arg("axes"), py::arg("keep_dims"))
     .def_static("get_inputs_name", &ReduceMean_Op::getInputsName)
     .def_static("get_outputs_name", &ReduceMean_Op::getOutputsName)
     .def_static("attributes_name", &ReduceMean_Op::staticGetAttrsName)
diff --git a/python_binding/operator/pybind_Reshape.cpp b/python_binding/operator/pybind_Reshape.cpp
index e987fd9cb36471af6a7fabc26ca51a887abc6880..ea8768f61fd8e2f9d9e5a668ac3e8838306ec7e1 100644
--- a/python_binding/operator/pybind_Reshape.cpp
+++ b/python_binding/operator/pybind_Reshape.cpp
@@ -20,6 +20,7 @@ namespace Aidge {
 
 void init_Reshape(py::module& m) {
     py::class_<Reshape_Op, std::shared_ptr<Reshape_Op>, Attributes, OperatorTensor>(m, "ReshapeOp", py::multiple_inheritance())
+    .def(py::init<const std::vector<std::int64_t>&>(), py::arg("shape"))
     .def_static("get_inputs_name", &Reshape_Op::getInputsName)
     .def_static("get_outputs_name", &Reshape_Op::getOutputsName);
     declare_registrable<Reshape_Op>(m, "ReshapeOp");
diff --git a/python_binding/operator/pybind_Scaling.cpp b/python_binding/operator/pybind_Scaling.cpp
index 23534f2d86cf8cebe0483dfa017f2d2e53c00a8c..0660cdb003ed4d5946f54786c0a51d9051d83d5a 100644
--- a/python_binding/operator/pybind_Scaling.cpp
+++ b/python_binding/operator/pybind_Scaling.cpp
@@ -22,6 +22,7 @@ namespace Aidge {
 void init_Scaling(py::module& m)
 {
     py::class_<Scaling_Op, std::shared_ptr<Scaling_Op>, Attributes, OperatorTensor>(m, "ScalingOp", py::multiple_inheritance())
+    .def(py::init<float, size_t, bool>(), py::arg("scaling_factor"), py::arg("nb_bits"), py::arg("is_output_unsigned"))
     .def_static("get_inputs_name", &Scaling_Op::getInputsName)
     .def_static("get_outputs_name", &Scaling_Op::getOutputsName)
     .def_static("attributes_name", &Scaling_Op::staticGetAttrsName);
diff --git a/python_binding/operator/pybind_Sigmoid.cpp b/python_binding/operator/pybind_Sigmoid.cpp
index b9cb39dc1563f426e6885c798a157d7697db2866..0ba94c73fcd1fb435194f8485567771a147ec616 100644
--- a/python_binding/operator/pybind_Sigmoid.cpp
+++ b/python_binding/operator/pybind_Sigmoid.cpp
@@ -20,6 +20,7 @@ namespace Aidge {
 
 void init_Sigmoid(py::module& m) {
     py::class_<Sigmoid_Op, std::shared_ptr<Sigmoid_Op>, OperatorTensor>(m, "SigmoidOp", py::multiple_inheritance())
+    .def(py::init<>())
     .def_static("get_inputs_name", &Sigmoid_Op::getInputsName)
     .def_static("get_outputs_name", &Sigmoid_Op::getOutputsName);
 
diff --git a/python_binding/operator/pybind_Slice.cpp b/python_binding/operator/pybind_Slice.cpp
index a7ee50a2097297621c304035a7ac4a73d14d892b..a024076e1dde4da6608ddc43861ffa20bfe217a8 100644
--- a/python_binding/operator/pybind_Slice.cpp
+++ b/python_binding/operator/pybind_Slice.cpp
@@ -21,6 +21,12 @@ namespace Aidge {
 
 void init_Slice(py::module& m) {
     py::class_<Slice_Op, std::shared_ptr<Slice_Op>, OperatorTensor>(m, "SliceOp", py::multiple_inheritance())
+    .def(py::init<const std::vector<std::int64_t>&,
+                  const std::vector<std::int64_t>&,
+                  const std::vector<std::int8_t>&>(),
+                  py::arg("starts"),
+                  py::arg("ends"),
+                  py::arg("axes"))
     .def_static("get_inputs_name", &Slice_Op::getInputsName)
     .def_static("get_outputs_name", &Slice_Op::getOutputsName);
     declare_registrable<Slice_Op>(m, "SliceOp");
diff --git a/python_binding/operator/pybind_Softmax.cpp b/python_binding/operator/pybind_Softmax.cpp
index 1a50705510098eb009d47933c165750bfa9d6139..becb6f35fb7413c042f6a902aadb602e4547ee01 100644
--- a/python_binding/operator/pybind_Softmax.cpp
+++ b/python_binding/operator/pybind_Softmax.cpp
@@ -21,6 +21,7 @@ namespace Aidge {
 
 void init_Softmax(py::module& m) {
     py::class_<Softmax_Op, std::shared_ptr<Softmax_Op>, Attributes, OperatorTensor>(m, "SoftmaxOp", py::multiple_inheritance())
+    .def(py::init<std::size_t>(), py::arg("axis"))
     .def_static("get_inputs_name", &Softmax_Op::getInputsName)
     .def_static("get_outputs_name", &Softmax_Op::getOutputsName)
     .def_static("attributes_name", &Softmax_Op::staticGetAttrsName);
diff --git a/python_binding/operator/pybind_Sqrt.cpp b/python_binding/operator/pybind_Sqrt.cpp
index 9efb9a668f86dc9a5340aeaa5708f7bbf205e3e4..9425eba06574c73339e8e4628ffded3449a8b4ab 100644
--- a/python_binding/operator/pybind_Sqrt.cpp
+++ b/python_binding/operator/pybind_Sqrt.cpp
@@ -20,6 +20,7 @@ namespace Aidge {
 
 void init_Sqrt(py::module& m) {
     py::class_<Sqrt_Op, std::shared_ptr<Sqrt_Op>, OperatorTensor>(m, "SqrtOp", py::multiple_inheritance())
+    .def(py::init<>())
     .def_static("get_inputs_name", &Sqrt_Op::getInputsName)
     .def_static("get_outputs_name", &Sqrt_Op::getOutputsName);
     declare_registrable<Sqrt_Op>(m, "SqrtOp");
diff --git a/python_binding/operator/pybind_Sub.cpp b/python_binding/operator/pybind_Sub.cpp
index 4d2989a1b4308bd1580ce3fc2e23d1a6be69085e..752490a72bc35ec8a0ab08dd8d51a31c887b4dc6 100644
--- a/python_binding/operator/pybind_Sub.cpp
+++ b/python_binding/operator/pybind_Sub.cpp
@@ -20,6 +20,7 @@ namespace Aidge {
 
 void init_Sub(py::module& m) {
     py::class_<Sub_Op, std::shared_ptr<Sub_Op>, OperatorTensor>(m, "SubOp", py::multiple_inheritance())
+    .def(py::init<>())
     .def_static("get_inputs_name", &Sub_Op::getInputsName)
     .def_static("get_outputs_name", &Sub_Op::getOutputsName);
     declare_registrable<Sub_Op>(m, "SubOp");
diff --git a/python_binding/operator/pybind_Tanh.cpp b/python_binding/operator/pybind_Tanh.cpp
index f2ef989696ca28a03fb34c2a3c1814aa2a561098..74cde8dd3831c8d29ca87e2314afc27276ec025f 100644
--- a/python_binding/operator/pybind_Tanh.cpp
+++ b/python_binding/operator/pybind_Tanh.cpp
@@ -20,6 +20,7 @@ namespace Aidge {
 
 void init_Tanh(py::module& m) {
     py::class_<Tanh_Op, std::shared_ptr<Tanh_Op>, OperatorTensor>(m, "TanhOp", py::multiple_inheritance())
+    .def(py::init<>())
     .def_static("get_inputs_name", &Tanh_Op::getInputsName)
     .def_static("get_outputs_name", &Tanh_Op::getOutputsName);
 
diff --git a/python_binding/operator/pybind_Transpose.cpp b/python_binding/operator/pybind_Transpose.cpp
index 7a857c4d1f8ba569ee7ccf711f60b4dfbdfddbd0..f3c000291dfca954bbed93b9400ac0bd8df8025b 100644
--- a/python_binding/operator/pybind_Transpose.cpp
+++ b/python_binding/operator/pybind_Transpose.cpp
@@ -29,6 +29,7 @@ void declare_Transpose(py::module &m) {
   const std::string pyClassName("TransposeOp");
   py::class_<Transpose_Op, std::shared_ptr<Transpose_Op>, Attributes, OperatorTensor>(
     m, "TransposeOp", py::multiple_inheritance())
+  .def(py::init<const std::vector<DimSize_t>&>(), py::arg("output_dims_order"))
   .def_static("get_inputs_name", &Transpose_Op::getInputsName)
   .def_static("get_outputs_name", &Transpose_Op::getOutputsName)
   .def_static("attributes_name", &Transpose_Op::staticGetAttrsName);