diff --git a/python/dune/xt/functions/CMakeLists.txt b/python/dune/xt/functions/CMakeLists.txt
index 84c655003cb98c34063823bf0724265c2b77c4b7..dddcb7a17e5ca132ed09a7bf7a21d655fa457b60 100644
--- a/python/dune/xt/functions/CMakeLists.txt
+++ b/python/dune/xt/functions/CMakeLists.txt
@@ -20,9 +20,9 @@ dune_pybindxi_add_module(_functions_function_interface_1d EXCLUDE_FROM_ALL funct
 dune_pybindxi_add_module(_functions_function_interface_2d EXCLUDE_FROM_ALL function-interface-2d.cc)
 dune_pybindxi_add_module(_functions_function_interface_3d EXCLUDE_FROM_ALL function-interface-3d.cc)
 dune_pybindxi_add_module(_functions_gridfunction EXCLUDE_FROM_ALL gridfunction.cc)
-dune_pybindxi_add_module(_functions_gridfunction_interface_1d EXCLUDE_FROM_ALL gridfunction-interface-1d.cc)
-dune_pybindxi_add_module(_functions_gridfunction_interface_2d EXCLUDE_FROM_ALL gridfunction-interface-2d.cc)
-dune_pybindxi_add_module(_functions_gridfunction_interface_3d EXCLUDE_FROM_ALL gridfunction-interface-3d.cc)
 dune_pybindxi_add_module(_functions_indicator EXCLUDE_FROM_ALL indicator.cc)
+dune_pybindxi_add_module(_functions_interfaces_grid_function_1d EXCLUDE_FROM_ALL interfaces/grid-function_1d.cc)
+dune_pybindxi_add_module(_functions_interfaces_grid_function_2d EXCLUDE_FROM_ALL interfaces/grid-function_2d.cc)
+dune_pybindxi_add_module(_functions_interfaces_grid_function_3d EXCLUDE_FROM_ALL interfaces/grid-function_3d.cc)
 dune_pybindxi_add_module(_functions_parametric_expression EXCLUDE_FROM_ALL parametric-expression.cc)
 dune_pybindxi_add_module(_functions_spe10 EXCLUDE_FROM_ALL spe10.cc)
diff --git a/python/dune/xt/functions/__init__.py b/python/dune/xt/functions/__init__.py
index a5d793dc7070480772372178f6e9e130f207af5d..5af0231fd68b824d32e38cd5f77cf2c03b9cb89d 100644
--- a/python/dune/xt/functions/__init__.py
+++ b/python/dune/xt/functions/__init__.py
@@ -26,10 +26,10 @@ for mod_name in (
         '_functions_function_as_grid_function',
         '_functions_function_interface_3d',
         '_functions_gridfunction',
-        '_functions_gridfunction_interface_1d',
-        '_functions_gridfunction_interface_2d',
-        '_functions_gridfunction_interface_3d',
         '_functions_indicator',
+        '_functions_interfaces_grid_function_1d',
+        '_functions_interfaces_grid_function_2d',
+        '_functions_interfaces_grid_function_3d',
         '_functions_parametric_expression',
         '_functions_spe10',
 ):
diff --git a/python/dune/xt/functions/base/combined-grid-function.hh b/python/dune/xt/functions/base/combined-grid-function.hh
new file mode 100644
index 0000000000000000000000000000000000000000..2de59e4108411fdb7db11e8be4e62b6defd49e20
--- /dev/null
+++ b/python/dune/xt/functions/base/combined-grid-function.hh
@@ -0,0 +1,149 @@
+// This file is part of the dune-xt project:
+//   https://github.com/dune-community/dune-xt
+// Copyright 2009-2018 dune-xt developers and contributors. All rights reserved.
+// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
+//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
+//          with "runtime exception" (http://www.dune-project.org/license.html)
+// Authors:
+//   Felix Schindler (2020)
+
+#ifndef PYTHON_DUNE_XT_FUNCTIONS_BASE_COMBINED_GRID_FUNCTION_HH
+#define PYTHON_DUNE_XT_FUNCTIONS_BASE_COMBINED_GRID_FUNCTION_HH
+
+#include <python/dune/xt/functions/interfaces/grid-function.hh>
+
+namespace Dune {
+namespace XT {
+namespace Functions {
+namespace bindings {
+
+
+template <class G, class E, size_t r = 1, size_t rC = 1, class R = double>
+class DifferenceGridFunction : public GridFunctionInterface<G, E, r, rC, R>
+{
+  using BaseType = GridFunctionInterface<G, E, r, rC, R>;
+
+public:
+  using base_type = typename BaseType::type;
+  using type = Functions::DifferenceGridFunction<base_type, base_type>;
+  using bound_type = pybind11::class_<type, base_type>;
+
+  static bound_type bind(pybind11::module& m,
+                         const std::string& grid_id,
+                         const std::string& layer_id = "",
+                         const std::string& class_id = "difference_grid_function")
+  {
+    namespace py = pybind11;
+    using namespace pybind11::literals;
+
+    const auto ClassName = Common::to_camel_case(BaseType::class_name(grid_id, layer_id, class_id));
+    bound_type c(m, ClassName.c_str(), Common::to_camel_case(class_id).c_str());
+
+    c.def(py::init<const base_type&, const base_type&>(), py::keep_alive<1, 2>(), py::keep_alive<1, 3>());
+
+    BaseType::addbind_methods(c);
+
+    return c;
+  }
+}; // class DifferenceGridFunction
+
+
+template <class G, class E, size_t r = 1, size_t rC = 1, class R = double>
+class SumGridFunction : public GridFunctionInterface<G, E, r, rC, R>
+{
+  using BaseType = GridFunctionInterface<G, E, r, rC, R>;
+
+public:
+  using base_type = typename BaseType::type;
+  using type = Functions::SumGridFunction<base_type, base_type>;
+  using bound_type = pybind11::class_<type, base_type>;
+
+  static bound_type bind(pybind11::module& m,
+                         const std::string& grid_id,
+                         const std::string& layer_id = "",
+                         const std::string& class_id = "sum_grid_function")
+  {
+    namespace py = pybind11;
+    using namespace pybind11::literals;
+
+    const auto ClassName = Common::to_camel_case(BaseType::class_name(grid_id, layer_id, class_id));
+    bound_type c(m, ClassName.c_str(), Common::to_camel_case(class_id).c_str());
+
+    c.def(py::init<const base_type&, const base_type&>(), py::keep_alive<1, 2>(), py::keep_alive<1, 3>());
+
+    BaseType::addbind_methods(c);
+
+    return c;
+  }
+}; // class SumGridFunction
+
+
+template <class G, class E, class R = double>
+class FractionGridFunction : public GridFunctionInterface<G, E, 1, 1, R>
+{
+  using BaseType = GridFunctionInterface<G, E, 1, 1, R>;
+
+public:
+  using base_type = typename BaseType::type;
+  using type = Functions::FractionGridFunction<base_type, base_type>;
+  using bound_type = pybind11::class_<type, base_type>;
+
+  static bound_type bind(pybind11::module& m,
+                         const std::string& grid_id,
+                         const std::string& layer_id = "",
+                         const std::string& class_id = "fraction_grid_function")
+  {
+    namespace py = pybind11;
+    using namespace pybind11::literals;
+
+    const auto ClassName = Common::to_camel_case(BaseType::class_name(grid_id, layer_id, class_id));
+    bound_type c(m, ClassName.c_str(), Common::to_camel_case(class_id).c_str());
+
+    c.def(py::init<const base_type&, const base_type&>(), py::keep_alive<1, 2>(), py::keep_alive<1, 3>());
+
+    BaseType::addbind_methods(c);
+
+    return c;
+  }
+}; // class FractionGridFunction
+
+
+template <class G, class E, size_t r = 1, size_t rC = 1, class R = double>
+class ProductGridFunction : public GridFunctionInterface<G, E, r, rC, R>
+{
+  using BaseType = GridFunctionInterface<G, E, r, rC, R>;
+
+public:
+  using base_type = typename BaseType::type;
+  using type = Functions::ProductGridFunction<Functions::GridFunctionInterface<E, 1, 1, R>, base_type>;
+  using bound_type = pybind11::class_<type, base_type>;
+
+  static bound_type bind(pybind11::module& m,
+                         const std::string& grid_id,
+                         const std::string& layer_id = "",
+                         const std::string& class_id = "product_grid_function")
+  {
+    namespace py = pybind11;
+    using namespace pybind11::literals;
+
+    const auto ClassName = Common::to_camel_case(BaseType::class_name(grid_id, layer_id, class_id));
+    bound_type c(m, ClassName.c_str(), Common::to_camel_case(class_id).c_str());
+
+    c.def(py::init<const Functions::GridFunctionInterface<E, 1, 1, R>&, const base_type&>(),
+          py::keep_alive<1, 2>(),
+          py::keep_alive<1, 3>());
+
+    BaseType::addbind_methods(c);
+
+    return c;
+  }
+}; // class ProductGridFunction
+
+
+} // namespace bindings
+} // namespace Functions
+} // namespace XT
+} // namespace Dune
+
+
+#endif // PYTHON_DUNE_XT_FUNCTIONS_BASE_COMBINED_GRID_FUNCTION_HH
diff --git a/python/dune/xt/functions/checkerboard.cc b/python/dune/xt/functions/checkerboard.cc
index 1d9dd13777cd95d9e624363e174e4ae582da11c1..6e547b1d95b32478386ea1c6161955251815d050 100644
--- a/python/dune/xt/functions/checkerboard.cc
+++ b/python/dune/xt/functions/checkerboard.cc
@@ -145,9 +145,9 @@ PYBIND11_MODULE(_functions_checkerboard, m)
   py::module::import("dune.xt.common");
   py::module::import("dune.xt.grid");
   py::module::import("dune.xt.la");
-  py::module::import("dune.xt.functions._functions_gridfunction_interface_1d");
-  py::module::import("dune.xt.functions._functions_gridfunction_interface_2d");
-  py::module::import("dune.xt.functions._functions_gridfunction_interface_3d");
+  py::module::import("dune.xt.functions._functions_interfaces_grid_function_1d");
+  py::module::import("dune.xt.functions._functions_interfaces_grid_function_2d");
+  py::module::import("dune.xt.functions._functions_interfaces_grid_function_3d");
 
   CheckerboardFunction_for_all_grids<>::bind(m);
 } // PYBIND11_MODULE(...)
diff --git a/python/dune/xt/functions/function-as-grid-function.cc b/python/dune/xt/functions/function-as-grid-function.cc
index 68ee9187284544b9e36fdbcedae5e73dc623132c..3ac206f7602654ca859d4227927fbb0d6df8f31e 100644
--- a/python/dune/xt/functions/function-as-grid-function.cc
+++ b/python/dune/xt/functions/function-as-grid-function.cc
@@ -66,9 +66,9 @@ PYBIND11_MODULE(_functions_function_as_grid_function, m)
   py::module::import("dune.xt.functions._functions_function_interface_1d");
   py::module::import("dune.xt.functions._functions_function_interface_2d");
   py::module::import("dune.xt.functions._functions_function_interface_3d");
-  py::module::import("dune.xt.functions._functions_gridfunction_interface_1d");
-  py::module::import("dune.xt.functions._functions_gridfunction_interface_2d");
-  py::module::import("dune.xt.functions._functions_gridfunction_interface_3d");
+  py::module::import("dune.xt.functions._functions_interfaces_grid_function_1d");
+  py::module::import("dune.xt.functions._functions_interfaces_grid_function_2d");
+  py::module::import("dune.xt.functions._functions_interfaces_grid_function_3d");
 
   all_grids(m);
 }
diff --git a/python/dune/xt/functions/gridfunction-interface-1d.cc b/python/dune/xt/functions/gridfunction-interface-1d.cc
deleted file mode 100644
index 342ccc44169647247b9adf9f8d0e72a4f53876ec..0000000000000000000000000000000000000000
--- a/python/dune/xt/functions/gridfunction-interface-1d.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// This file is part of the dune-xt project:
-//   https://github.com/dune-community/dune-xt
-// Copyright 2009-2020 dune-xt developers and contributors. All rights reserved.
-// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
-//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
-//          with "runtime exception" (http://www.dune-project.org/license.html)
-// Authors:
-//   Felix Schindler (2019)
-//   René Fritze     (2019)
-//   Tobias Leibner  (2019 - 2020)
-
-#include "config.h"
-
-#include <string>
-#include <vector>
-
-#include <dune/common/parallel/mpihelper.hh>
-
-#include <dune/pybindxi/pybind11.h>
-#include <dune/pybindxi/stl.h>
-
-#include <python/dune/xt/common/bindings.hh>
-#include <python/dune/xt/common/exceptions.bindings.hh>
-#include <python/dune/xt/grid/grids.bindings.hh>
-
-#include "gridfunction-interface.hh"
-
-
-template <class Tuple = Dune::XT::Grid::Available1dGridTypes>
-void bind_all_1d_grids(pybind11::module& m)
-{
-  Dune::XT::Common::bindings::guarded_bind([&]() { //  different grids but same entity
-    Dune::XT::Functions::bindings::addbind_GridFunctionInterface_all_dims<typename Tuple::head_type>(m);
-  });
-  bind_all_1d_grids<typename Tuple::tail_type>(m);
-}
-
-template <>
-void bind_all_1d_grids<boost::tuples::null_type>(pybind11::module&)
-{}
-
-
-PYBIND11_MODULE(_functions_gridfunction_interface_1d, m)
-{
-  namespace py = pybind11;
-
-  py::module::import("dune.xt.common");
-  py::module::import("dune.xt.la");
-  py::module::import("dune.xt.grid");
-  py::module::import("dune.xt.functions._functions_function_interface_1d");
-
-  bind_all_1d_grids(m);
-} // PYBIND11_MODULE(...)
diff --git a/python/dune/xt/functions/gridfunction-interface-2d.cc b/python/dune/xt/functions/gridfunction-interface-2d.cc
deleted file mode 100644
index 0d003986e08d1d1ace735b8a62d49e187bd61b82..0000000000000000000000000000000000000000
--- a/python/dune/xt/functions/gridfunction-interface-2d.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// This file is part of the dune-xt project:
-//   https://github.com/dune-community/dune-xt
-// Copyright 2009-2020 dune-xt developers and contributors. All rights reserved.
-// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
-//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
-//          with "runtime exception" (http://www.dune-project.org/license.html)
-// Authors:
-//   Felix Schindler (2019)
-//   René Fritze     (2019)
-//   Tobias Leibner  (2019 - 2020)
-
-#include "config.h"
-
-#include <string>
-#include <vector>
-
-#include <dune/common/parallel/mpihelper.hh>
-
-#include <dune/pybindxi/pybind11.h>
-#include <dune/pybindxi/stl.h>
-
-#include <python/dune/xt/common/bindings.hh>
-#include <python/dune/xt/common/exceptions.bindings.hh>
-#include <python/dune/xt/grid/grids.bindings.hh>
-
-#include "gridfunction-interface.hh"
-
-
-template <class Tuple = Dune::XT::Grid::Available2dGridTypes>
-void bind_all_2d_grids(pybind11::module& m)
-{
-  Dune::XT::Common::bindings::guarded_bind([&]() { //  different grids but same entity
-    Dune::XT::Functions::bindings::addbind_GridFunctionInterface_all_dims<typename Tuple::head_type>(m);
-  });
-  bind_all_2d_grids<typename Tuple::tail_type>(m);
-}
-
-template <>
-void bind_all_2d_grids<boost::tuples::null_type>(pybind11::module&)
-{}
-
-
-PYBIND11_MODULE(_functions_gridfunction_interface_2d, m)
-{
-  namespace py = pybind11;
-
-  py::module::import("dune.xt.common");
-  py::module::import("dune.xt.la");
-  py::module::import("dune.xt.grid");
-  py::module::import("dune.xt.functions._functions_function_interface_2d");
-
-  bind_all_2d_grids(m);
-} // PYBIND11_MODULE(...)
diff --git a/python/dune/xt/functions/gridfunction-interface-3d.cc b/python/dune/xt/functions/gridfunction-interface-3d.cc
deleted file mode 100644
index db8793bba427a1606733ade8a007b8466eefde55..0000000000000000000000000000000000000000
--- a/python/dune/xt/functions/gridfunction-interface-3d.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// This file is part of the dune-xt project:
-//   https://github.com/dune-community/dune-xt
-// Copyright 2009-2020 dune-xt developers and contributors. All rights reserved.
-// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
-//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
-//          with "runtime exception" (http://www.dune-project.org/license.html)
-// Authors:
-//   Felix Schindler (2019)
-//   René Fritze     (2019)
-//   Tobias Leibner  (2019 - 2020)
-
-#include "config.h"
-
-#include <string>
-#include <vector>
-
-#include <dune/common/parallel/mpihelper.hh>
-
-#include <dune/pybindxi/pybind11.h>
-#include <dune/pybindxi/stl.h>
-
-#include <python/dune/xt/common/bindings.hh>
-#include <python/dune/xt/common/exceptions.bindings.hh>
-#include <python/dune/xt/grid/grids.bindings.hh>
-
-#include "gridfunction-interface.hh"
-
-
-template <class Tuple = Dune::XT::Grid::Available3dGridTypes>
-void bind_all_3d_grids(pybind11::module& m)
-{
-  Dune::XT::Common::bindings::guarded_bind([&]() { //  different grids but same entity
-    Dune::XT::Functions::bindings::addbind_GridFunctionInterface_all_dims<typename Tuple::head_type>(m);
-  });
-  bind_all_3d_grids<typename Tuple::tail_type>(m);
-}
-
-template <>
-void bind_all_3d_grids<boost::tuples::null_type>(pybind11::module&)
-{}
-
-
-PYBIND11_MODULE(_functions_gridfunction_interface_3d, m)
-{
-  namespace py = pybind11;
-
-  py::module::import("dune.xt.common");
-  py::module::import("dune.xt.la");
-  py::module::import("dune.xt.grid");
-  py::module::import("dune.xt.functions._functions_function_interface_3d");
-
-  bind_all_3d_grids(m);
-} // PYBIND11_MODULE(...)
diff --git a/python/dune/xt/functions/gridfunction-interface.hh b/python/dune/xt/functions/gridfunction-interface.hh
deleted file mode 100644
index 9a73c627bbb6067a4d01d0cad321c12d91bd56ea..0000000000000000000000000000000000000000
--- a/python/dune/xt/functions/gridfunction-interface.hh
+++ /dev/null
@@ -1,451 +0,0 @@
-// This file is part of the dune-xt project:
-//   https://github.com/dune-community/dune-xt
-// Copyright 2009-2020 dune-xt developers and contributors. All rights reserved.
-// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
-//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
-//          with "runtime exception" (http://www.dune-project.org/license.html)
-// Authors:
-//   Felix Schindler (2016 - 2019)
-//   René Fritze     (2018 - 2019)
-//   Tim Keil        (2018)
-//   Tobias Leibner  (2018, 2020)
-
-#ifndef DUNE_XT_FUNCTIONS_INTERFACE_PBH
-#define DUNE_XT_FUNCTIONS_INTERFACE_PBH
-
-#include <dune/pybindxi/pybind11.h>
-#include <dune/pybindxi/operators.h>
-
-#include <python/dune/xt/common/bindings.hh>
-#include <python/dune/xt/grid/grids.bindings.hh>
-#include <dune/xt/grid/gridprovider/provider.hh>
-
-#include <dune/xt/functions/interfaces/grid-function.hh>
-#include <dune/xt/functions/interfaces/function.hh>
-
-namespace Dune {
-namespace XT {
-namespace Functions {
-namespace bindings {
-namespace internal {
-
-
-template <class L, class R, CombinationType comb>
-struct get_combined
-{}; // struct get_combined
-
-template <class L, class R>
-struct get_combined<L, R, CombinationType::difference>
-{
-  typedef DifferenceFunction<L, R> type;
-
-  static std::string id()
-  {
-    return "DifferenceFunction";
-  }
-
-  static std::string doc()
-  {
-    return "difference";
-  }
-
-  static std::string op()
-  {
-    return "__sub__";
-  }
-
-  static auto call(const L& l, const R& r) -> decltype(l - r)
-  {
-    return l - r;
-  }
-}; // struct get_combined
-
-template <class L, class R>
-struct get_combined<L, R, CombinationType::sum>
-{
-  typedef SumFunction<L, R> type;
-
-  static std::string id()
-  {
-    return "SumFunction";
-  }
-
-  static std::string doc()
-  {
-    return "sum";
-  }
-
-  static std::string op()
-  {
-    return "__add__";
-  }
-
-  static auto call(const L& l, const R& r) -> decltype(l + r)
-  {
-    return l + r;
-  }
-}; // struct get_combined
-
-template <class L, class R>
-struct get_combined<L, R, CombinationType::product>
-{
-  typedef ProductFunction<L, R> type;
-
-  static std::string id()
-  {
-    return "ProductFunction";
-  }
-
-  static std::string doc()
-  {
-    return "product";
-  }
-
-  static std::string op()
-  {
-    return "__mul__";
-  }
-
-  static auto call(const L& l, const R& r) -> decltype(l * r)
-  {
-    return l * r;
-  }
-}; // struct get_combined
-
-
-/**
- * grid_combined
- */
-
-template <class L, class R, CombinationType comb>
-struct get_grid_combined
-{}; // struct get_grid_combined
-
-template <class L, class R>
-struct get_grid_combined<L, R, CombinationType::difference>
-{
-  typedef DifferenceGridFunction<L, R> type;
-
-  static std::string id()
-  {
-    return "DifferenceGridFunction";
-  }
-
-  static std::string doc()
-  {
-    return "difference";
-  }
-
-  static std::string op()
-  {
-    return "__sub__";
-  }
-
-  static auto call(const L& l, const R& r) -> decltype(l - r)
-  {
-    return l - r;
-  }
-}; // struct get_grid_combined
-
-template <class L, class R>
-struct get_grid_combined<L, R, CombinationType::sum>
-{
-  typedef SumGridFunction<L, R> type;
-
-  static std::string id()
-  {
-    return "SumGridFunction";
-  }
-
-  static std::string doc()
-  {
-    return "sum";
-  }
-
-  static std::string op()
-  {
-    return "__add__";
-  }
-
-  static auto call(const L& l, const R& r) -> decltype(l + r)
-  {
-    return l + r;
-  }
-}; // struct get_grid_combined
-
-template <class L, class R>
-struct get_grid_combined<L, R, CombinationType::product>
-{
-  typedef ProductGridFunction<L, R> type;
-
-  static std::string id()
-  {
-    return "ProductGridFunction";
-  }
-
-  static std::string doc()
-  {
-    return "product";
-  }
-
-  static std::string op()
-  {
-    return "__mul__";
-  }
-
-  static auto call(const L& l, const R& r) -> decltype(l * r)
-  {
-    return l * r;
-  }
-}; // struct get_grid_combined
-
-// template <class G>
-// struct Divergence
-//{
-//  template <size_t d, size_t r, size_t rC, bool dims_match = (d == r) && (rC == 1)>
-//  struct helper
-//  {
-//    template <class E, class R>
-//    static void addbind(pybind11::module& m, pybind11::class_<GridFunctionInterface<E, d, 1, R>>& c)
-//    {
-//      namespace py = pybind11;
-//      using namespace pybind11::literals;
-//      using Common::to_string;
-
-//      try { // guard since we might not be the first to do bind this combination
-//        py::class_<DivergenceFunction<GridFunctionInterface<E, d, 1, R>>,
-//                   GridFunctionInterface<E, d, 1, R>>(
-//            m,
-//            Common::to_camel_case(
-//                "divergence_of_function_from_" + Grid::bindings::grid_name<G>::value() + "_to_" + to_string(r) + "x"
-//                + to_string(rC))
-//                .c_str(),
-//            "DivergenceFunction");
-//      } catch (std::runtime_error&) {
-//      }
-
-//      c.def("divergence",
-//            [](const GridFunctionInterface<E, d, 1, R>& self, const std::string& name) {
-//              return new DivergenceFunction<GridFunctionInterface<E, d, 1, R>>(self, name);
-//            },
-//            "name"_a = "",
-//            py::keep_alive<0, 1>());
-//    } // ... addbind(...)
-//  }; // struct helper<..., true>
-
-//  template <size_t d, size_t r, size_t rC>
-//  struct helper<d, r, rC, false>
-//  {
-//    template <class E, class R>
-//    static void addbind(pybind11::module& /*m*/, pybind11::class_<GridFunctionInterface<E, r, rC, R>>& /*c*/)
-//    {
-//    }
-//  }; // struct helper<..., false>
-
-//  template <class E, size_t d, class R, size_t r, size_t rC>
-//  static void addbind(pybind11::module& m, pybind11::class_<GridFunctionInterface<E, r, rC, R>>& c)
-//  {
-//    helper<d, r, rC>::addbind(m, c);
-//  } // ... addbind(...)
-//}; // struct Divergence
-
-
-} // namespace internal
-
-
-/**
- * \note We would like to drop the d template paremter and use either of
-\code
-static const           size_t d = G::dimension;
-static const constexpr size_t d = G::dimension;
-\endcode
- *       but this triggers a bug in gcc-4.9, see e.g.: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59937
- */
-template <class G,
-          size_t d,
-          CombinationType comb,
-          size_t lr,
-          size_t lrC,
-          size_t rr,
-          size_t rrC,
-          class C = typename internal::get_grid_combined<
-              GridFunctionInterface<typename G::template Codim<0>::Entity, lr, lrC, double>,
-              GridFunctionInterface<typename G::template Codim<0>::Entity, rr, rrC, double>,
-              comb>::type>
-pybind11::class_<C,
-                 GridFunctionInterface<typename G::template Codim<0>::Entity, C::range_dim, C::range_dim_cols, double>>
-bind_combined_GridFunction(pybind11::module& m, const std::string& grid_id)
-{
-  namespace py = pybind11;
-
-  typedef typename G::template Codim<0>::Entity E;
-  typedef double R;
-  typedef GridFunctionInterface<E, lr, lrC, R> Left;
-  typedef GridFunctionInterface<E, rr, rrC, R> Right;
-  static const size_t r = C::range_dim;
-  static const size_t rC = C::range_dim_cols;
-  const std::string id = internal::get_grid_combined<Left, Right, comb>::id();
-  const std::string op = internal::get_grid_combined<Left, Right, comb>::doc();
-  const std::string class_name = id + "__" + grid_id + "_to_" + Common::to_string(r) + "x" + Common::to_string(rC);
-  const std::string doc = class_name + " (as a " + op + " of functions of dimensions " + Common::to_string(lr) + "x"
-                          + Common::to_string(lrC) + " and " + Common::to_string(rr) + "x" + Common::to_string(rrC)
-                          + ")";
-
-  py::class_<C, GridFunctionInterface<E, r, rC, R>> c(m, std::string(class_name).c_str(), doc.c_str());
-
-  c.def_property_readonly("static_id", [](const C& /*self*/) { return C::static_id(); });
-
-  return c;
-} // ... bind_combined_GridFunction(...)
-
-
-/**
- * \note We would like to drop the d template paremter and use either of
-\code
-static const           size_t d = G::dimension;
-static const constexpr size_t d = G::dimension;
-\endcode
- *       but this triggers a bug in gcc-4.9, see e.g.: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59937
- */
-template <class G, size_t d, CombinationType comb, size_t r, size_t rC, size_t oR, size_t orC, class C>
-void addbind_GridFunctionInterface_combined_op(C& c)
-{
-  namespace py = pybind11;
-
-  typedef typename G::template Codim<0>::Entity E;
-  typedef GridFunctionInterface<E, r, rC, double> S;
-  typedef GridFunctionInterface<E, oR, orC, double> O;
-
-  c.def(
-      internal::get_grid_combined<S, O, comb>::op().c_str(),
-      [](const S& self, const O& other) { return internal::get_grid_combined<S, O, comb>::call(self, other); },
-      py::keep_alive<0, 1>(),
-      py::keep_alive<0, 2>());
-} // ... addbind_GridFunctionInterface_combined_op(...)
-
-
-template <class G, size_t r, size_t rC>
-pybind11::class_<GridFunctionInterface<typename G::template Codim<0>::Entity, r, rC, double>>
-bind_GridFunctionInterface(pybind11::module& m, const std::string& grid_id)
-{
-  namespace py = pybind11;
-  using namespace pybind11::literals;
-
-  typedef GridFunctionInterface<typename G::template Codim<0>::Entity, r, rC, double> C;
-
-  py::class_<C> c(
-      m,
-      std::string("GridFunctionInterface__" + grid_id + "_to_" + Common::to_string(r) + "x" + Common::to_string(rC))
-          .c_str(),
-      std::string("GridFunctionInterface__" + grid_id + "_to_" + Common::to_string(r) + "x" + Common::to_string(rC))
-          .c_str());
-
-  c.def_property_readonly("dim_domain", [](const C& /*self*/) { return size_t(G::dimension); });
-  if (rC == 1)
-    c.def_property_readonly("dim_range", [](const C& /*self*/) { return size_t(r); });
-  else
-    c.def_property_readonly("dim_range", [](const C& /*self*/) { return std::make_pair(size_t(r), size_t(rC)); });
-  c.def_property_readonly("static_id", [](const C& /*self*/) { return C::static_id(); });
-  c.def_property_readonly("name", [](const C& self) { return self.name(); });
-
-  c.def(
-      "visualize",
-      [](const C& self,
-         const Grid::GridProvider<G>& grid_provider,
-         const std::string& filename,
-         const bool subsampling) { self.visualize(grid_provider.leaf_view(), filename, subsampling); },
-      "grid"_a,
-      "filename"_a,
-      "subsampling"_a = true);
-
-  // internal::Divergence<G>::addbind(m, c);
-
-  return c;
-} // ... bind_GridFunctionInterface(...)
-
-
-template <class G>
-void addbind_GridFunctionInterface_all_dims(pybind11::module& m)
-{
-  using namespace Dune::XT::Functions;
-  const auto grid_id = Dune::XT::Grid::bindings::grid_name<G>::value();
-  constexpr const auto diff = CombinationType::difference;
-  constexpr const auto sum = CombinationType::sum;
-  constexpr const auto prod = CombinationType::product;
-  constexpr const auto g_dim = G::dimension;
-
-  auto i_1_1 = bind_GridFunctionInterface<G, 1, 1>(m, grid_id);
-  auto i_1_2 = bind_GridFunctionInterface<G, 1, 2>(m, grid_id);
-  auto i_1_3 = bind_GridFunctionInterface<G, 1, 3>(m, grid_id);
-  auto i_2_1 = bind_GridFunctionInterface<G, 2, 1>(m, grid_id);
-  auto i_2_2 = bind_GridFunctionInterface<G, 2, 2>(m, grid_id);
-  auto i_2_3 = bind_GridFunctionInterface<G, 2, 3>(m, grid_id);
-  auto i_3_1 = bind_GridFunctionInterface<G, 3, 1>(m, grid_id);
-  auto i_3_2 = bind_GridFunctionInterface<G, 3, 2>(m, grid_id);
-  auto i_3_3 = bind_GridFunctionInterface<G, 3, 3>(m, grid_id);
-
-  bind_combined_GridFunction<G, g_dim, diff, 1, 1, 1, 1>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, diff, 1, 1, 1, 1>(i_1_1);
-  bind_combined_GridFunction<G, g_dim, diff, 1, 2, 1, 2>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, diff, 1, 2, 1, 2>(i_1_2);
-  bind_combined_GridFunction<G, g_dim, diff, 1, 3, 1, 3>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, diff, 1, 3, 1, 3>(i_1_3);
-  bind_combined_GridFunction<G, g_dim, diff, 2, 1, 2, 1>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, diff, 2, 1, 2, 1>(i_2_1);
-  bind_combined_GridFunction<G, g_dim, diff, 2, 2, 2, 2>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, diff, 2, 2, 2, 2>(i_2_2);
-  bind_combined_GridFunction<G, g_dim, diff, 2, 3, 2, 3>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, diff, 2, 3, 2, 3>(i_2_3);
-  bind_combined_GridFunction<G, g_dim, diff, 3, 1, 3, 1>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, diff, 3, 1, 3, 1>(i_3_1);
-  bind_combined_GridFunction<G, g_dim, diff, 3, 2, 3, 2>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, diff, 3, 2, 3, 2>(i_3_2);
-  bind_combined_GridFunction<G, g_dim, diff, 3, 3, 3, 3>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, diff, 3, 3, 3, 3>(i_3_3);
-
-  bind_combined_GridFunction<G, g_dim, sum, 1, 1, 1, 1>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, sum, 1, 1, 1, 1>(i_1_1);
-  bind_combined_GridFunction<G, g_dim, sum, 1, 2, 1, 2>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, sum, 1, 2, 1, 2>(i_1_2);
-  bind_combined_GridFunction<G, g_dim, sum, 1, 3, 1, 3>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, sum, 1, 3, 1, 3>(i_1_3);
-  bind_combined_GridFunction<G, g_dim, sum, 2, 1, 2, 1>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, sum, 2, 1, 2, 1>(i_2_1);
-  bind_combined_GridFunction<G, g_dim, sum, 2, 2, 2, 2>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, sum, 2, 2, 2, 2>(i_2_2);
-  bind_combined_GridFunction<G, g_dim, sum, 2, 3, 2, 3>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, sum, 2, 3, 2, 3>(i_2_3);
-  bind_combined_GridFunction<G, g_dim, sum, 3, 1, 3, 1>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, sum, 3, 1, 3, 1>(i_3_1);
-  bind_combined_GridFunction<G, g_dim, sum, 3, 2, 3, 2>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, sum, 3, 2, 3, 2>(i_3_2);
-  bind_combined_GridFunction<G, g_dim, sum, 3, 3, 3, 3>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, sum, 3, 3, 3, 3>(i_3_3);
-
-  bind_combined_GridFunction<G, g_dim, prod, 1, 1, 1, 1>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, prod, 1, 1, 1, 1>(i_1_1);
-  bind_combined_GridFunction<G, g_dim, prod, 1, 1, 1, 2>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, prod, 1, 1, 1, 2>(i_1_1);
-  bind_combined_GridFunction<G, g_dim, prod, 1, 1, 1, 3>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, prod, 1, 1, 1, 3>(i_1_1);
-  bind_combined_GridFunction<G, g_dim, prod, 1, 1, 2, 1>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, prod, 1, 1, 2, 1>(i_1_1);
-  bind_combined_GridFunction<G, g_dim, prod, 1, 1, 2, 2>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, prod, 1, 1, 2, 2>(i_1_1);
-  bind_combined_GridFunction<G, g_dim, prod, 1, 1, 2, 3>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, prod, 1, 1, 2, 3>(i_1_1);
-  bind_combined_GridFunction<G, g_dim, prod, 1, 1, 3, 1>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, prod, 1, 1, 3, 1>(i_1_1);
-  bind_combined_GridFunction<G, g_dim, prod, 1, 1, 3, 2>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, prod, 1, 1, 3, 2>(i_1_1);
-  bind_combined_GridFunction<G, g_dim, prod, 1, 1, 3, 3>(m, grid_id);
-  addbind_GridFunctionInterface_combined_op<G, g_dim, prod, 1, 1, 3, 3>(i_1_1);
-} // ... addbind_GridFunctionInterface_all_dims(...)
-
-
-} // namespace bindings
-} // namespace Functions
-} // namespace XT
-} // namespace Dune
-
-#endif // DUNE_XT_FUNCTIONS_INTERFACE_PBH
diff --git a/python/dune/xt/functions/gridfunction.cc b/python/dune/xt/functions/gridfunction.cc
index 1e822eb15f95f89854103df142e2d03399e59866..de7451575c4b0e4dcfea74cb3d0f1cf739672d82 100644
--- a/python/dune/xt/functions/gridfunction.cc
+++ b/python/dune/xt/functions/gridfunction.cc
@@ -638,9 +638,9 @@ PYBIND11_MODULE(_functions_gridfunction, m)
   py::module::import("dune.xt.common");
   py::module::import("dune.xt.grid");
   py::module::import("dune.xt.la");
-  py::module::import("dune.xt.functions._functions_gridfunction_interface_1d");
-  py::module::import("dune.xt.functions._functions_gridfunction_interface_2d");
-  py::module::import("dune.xt.functions._functions_gridfunction_interface_3d");
+  py::module::import("dune.xt.functions._functions_interfaces_grid_function_1d");
+  py::module::import("dune.xt.functions._functions_interfaces_grid_function_2d");
+  py::module::import("dune.xt.functions._functions_interfaces_grid_function_3d");
 
   GridFunction_for_all_grids<>::bind(m);
 } // PYBIND11_MODULE(...)
diff --git a/python/dune/xt/functions/indicator.cc b/python/dune/xt/functions/indicator.cc
index f866bfe89611430854c5ff8f1bbf270b9eda31cb..8c81752cbcef9fa71c0d0ad63289c7abfdf4d17e 100644
--- a/python/dune/xt/functions/indicator.cc
+++ b/python/dune/xt/functions/indicator.cc
@@ -57,9 +57,9 @@ PYBIND11_MODULE(_functions_indicator, m)
   py::module::import("dune.xt.common");
   py::module::import("dune.xt.la");
   py::module::import("dune.xt.grid");
-  py::module::import("dune.xt.functions._functions_gridfunction_interface_1d");
-  py::module::import("dune.xt.functions._functions_gridfunction_interface_2d");
-  py::module::import("dune.xt.functions._functions_gridfunction_interface_3d");
+  py::module::import("dune.xt.functions._functions_interfaces_grid_function_1d");
+  py::module::import("dune.xt.functions._functions_interfaces_grid_function_2d");
+  py::module::import("dune.xt.functions._functions_interfaces_grid_function_3d");
 
   all_grids(m);
 
diff --git a/python/dune/xt/functions/interfaces/grid-function.hh b/python/dune/xt/functions/interfaces/grid-function.hh
new file mode 100644
index 0000000000000000000000000000000000000000..61e1014ccc379b7191468c7f61f07d5c96e2ce45
--- /dev/null
+++ b/python/dune/xt/functions/interfaces/grid-function.hh
@@ -0,0 +1,163 @@
+// This file is part of the dune-xt project:
+//   https://github.com/dune-community/dune-xt
+// Copyright 2009-2018 dune-xt developers and contributors. All rights reserved.
+// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
+//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
+//          with "runtime exception" (http://www.dune-project.org/license.html)
+// Authors:
+//   Felix Schindler (2020)
+
+#ifndef PYTHON_DUNE_XT_FUNCTIONS_INTERFACES_GRID_FUNCTION_HH
+#define PYTHON_DUNE_XT_FUNCTIONS_INTERFACES_GRID_FUNCTION_HH
+
+#include <dune/pybindxi/pybind11.h>
+
+#include <dune/xt/common/string.hh>
+#include <dune/xt/grid/gridprovider/provider.hh>
+#include <dune/xt/functions/interfaces/grid-function.hh>
+
+#include <python/dune/xt/common/parameter.hh>
+
+namespace Dune {
+namespace XT {
+namespace Functions {
+namespace bindings {
+
+
+template <class G, class E, size_t r = 1, size_t rC = 1, class R = double>
+class GridFunctionInterface
+{
+  using GP = XT::Grid::GridProvider<G>;
+  static const constexpr size_t d = G::dimension;
+
+  template <bool scalar = (r == 1 && rC == 1), bool anything = false>
+  struct fraction_helper // <true, ...>
+  {
+    template <class T, typename... options>
+    static void addbind(pybind11::class_<T, options...>& c)
+    {
+      namespace py = pybind11;
+
+      c.def(
+          "__truediv__",
+          [](const T& self, const type& other) { return std::make_unique<decltype(other / self)>(other / self); },
+          py::keep_alive<0, 1>(),
+          py::keep_alive<0, 2>(),
+          py::is_operator());
+    }
+  };
+
+  template <bool anything>
+  struct fraction_helper<false, anything>
+  {
+    template <class T, typename... options>
+    static void addbind(pybind11::class_<T, options...>& /*c*/)
+    {}
+  };
+
+public:
+  using type = Functions::GridFunctionInterface<E, r, rC, R>;
+  using bound_type = pybind11::class_<type>;
+
+  static std::string class_name(const std::string& grid_id, const std::string& layer_id, const std::string& class_id)
+  {
+    std::string ret = class_id;
+    ret += "_" + grid_id;
+    if (!layer_id.empty())
+      ret += "_" + layer_id;
+    ret += "_to_" + Common::to_string(r);
+    if (rC > 1)
+      ret += "x" + Common::to_string(rC);
+    ret += "d";
+    if (!std::is_same<R, double>::value)
+      ret += "_" + Common::Typename<R>::value(/*fail_wo_typeid=*/true);
+    return ret;
+  } // ... class_name(...)
+
+  template <class T, typename... options>
+  static void addbind_methods(pybind11::class_<T, options...>& c)
+  {
+    namespace py = pybind11;
+    using namespace pybind11::literals;
+
+    // our methods
+    c.def(
+        "visualize",
+        [](const T& self, const GP& grid_provider, const std::string& filename, const bool subsampling) {
+          self.visualize(grid_provider.leaf_view(), filename, subsampling);
+        },
+        "grid"_a,
+        "filename"_a,
+        "subsampling"_a = true);
+    // our operators
+    c.def(
+        "__add__",
+        [](const T& self, const type& other) { return std::make_unique<decltype(self + other)>(self + other); },
+        py::keep_alive<0, 1>(),
+        py::keep_alive<0, 2>(),
+        py::is_operator());
+    c.def(
+        "__sub__",
+        [](const T& self, const type& other) { return std::make_unique<decltype(self - other)>(self - other); },
+        py::keep_alive<0, 1>(),
+        py::keep_alive<0, 2>(),
+        py::is_operator());
+    c.def(
+        "__mul__",
+        [](const T& self, const Functions::GridFunctionInterface<E, 1, 1, R>& other) {
+          return std::make_unique<decltype(other * self)>(other * self);
+        },
+        py::keep_alive<0, 1>(),
+        py::keep_alive<0, 2>(),
+        py::is_operator());
+    if (r > 1 || rC > 1)
+      c.def(
+          "__rmul__",
+          [](const T& self, const Functions::GridFunctionInterface<E, 1, 1, R>& other) {
+            return std::make_unique<decltype(other * self)>(other * self);
+          },
+          py::keep_alive<0, 1>(),
+          py::keep_alive<0, 2>(),
+          py::is_operator());
+
+    // ParametricInterface methods
+    c.def(
+        "parse_parameter", [](const T& self, const Common::Parameter& mu) { return self.parse_parameter(mu); }, "mu"_a);
+  } // ... addbind_methods(...)
+
+  static bound_type bind(pybind11::module& m,
+                         const std::string& grid_id,
+                         const std::string& layer_id = "",
+                         const std::string& class_id = "grid_function_interface")
+  {
+    namespace py = pybind11;
+    using namespace pybind11::literals;
+
+    const auto ClassName = Common::to_camel_case(class_name(grid_id, layer_id, class_id));
+    bound_type c(m, ClassName.c_str(), Common::to_camel_case(class_id).c_str());
+
+    // our properties
+    c.def_property_readonly("dim_domain", [](type&) { return size_t(d); });
+    if (rC == 1)
+      c.def_property_readonly("dim_range", [](type&) { return size_t(r); });
+    else
+      c.def_property_readonly("dim_range", [](type&) { return std::make_pair(size_t(r), size_t(rC)); });
+    c.def_property_readonly("name", [](type& self) { return self.name(); });
+    // ParametricInterface properties
+    c.def_property_readonly("is_parametric", [](type& self) { return self.is_parametric(); });
+    c.def_property_readonly("parameter_type", [](type& self) { return self.parameter_type(); });
+
+    addbind_methods(c);
+
+    return c;
+  }
+}; // class GridFunctionInterface
+
+
+} // namespace bindings
+} // namespace Functions
+} // namespace XT
+} // namespace Dune
+
+
+#endif // PYTHON_DUNE_XT_FUNCTIONS_INTERFACES_GRID_FUNCTION_HH
diff --git a/python/dune/xt/functions/interfaces/grid-function_1d.cc b/python/dune/xt/functions/interfaces/grid-function_1d.cc
new file mode 100644
index 0000000000000000000000000000000000000000..93cfa0bd8f8d1f35ef18fa8f04ef97ca03c68860
--- /dev/null
+++ b/python/dune/xt/functions/interfaces/grid-function_1d.cc
@@ -0,0 +1,26 @@
+// This file is part of the dune-xt project:
+//   https://github.com/dune-community/dune-xt
+// Copyright 2009-2018 dune-xt developers and contributors. All rights reserved.
+// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
+//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
+//          with "runtime exception" (http://www.dune-project.org/license.html)
+// Authors:
+//   Felix Schindler (2020)
+
+#include "config.h"
+
+#include <dune/xt/grid/grids.hh>
+
+#include "grid-function_for_all_grids.hh"
+
+
+PYBIND11_MODULE(_functions_interfaces_grid_function_1d, m)
+{
+  namespace py = pybind11;
+
+  py::module::import("dune.xt.common");
+  py::module::import("dune.xt.grid");
+  py::module::import("dune.xt.la");
+
+  GridFunctionInterface_for_all_grids<boost::tuple<ONED_1D>>::bind(m);
+} // PYBIND11_MODULE(...)
diff --git a/python/dune/xt/functions/interfaces/grid-function_2d.cc b/python/dune/xt/functions/interfaces/grid-function_2d.cc
new file mode 100644
index 0000000000000000000000000000000000000000..fda25f52673739c8fa46599fff8de566e2ea70d9
--- /dev/null
+++ b/python/dune/xt/functions/interfaces/grid-function_2d.cc
@@ -0,0 +1,31 @@
+// This file is part of the dune-xt project:
+//   https://github.com/dune-community/dune-xt
+// Copyright 2009-2018 dune-xt developers and contributors. All rights reserved.
+// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
+//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
+//          with "runtime exception" (http://www.dune-project.org/license.html)
+// Authors:
+//   Felix Schindler (2020)
+
+#include "config.h"
+
+#include <dune/xt/grid/grids.hh>
+
+#include "grid-function_for_all_grids.hh"
+
+
+PYBIND11_MODULE(_functions_interfaces_grid_function_2d, m)
+{
+  namespace py = pybind11;
+
+  py::module::import("dune.xt.common");
+  py::module::import("dune.xt.grid");
+  py::module::import("dune.xt.la");
+
+  GridFunctionInterface_for_all_grids<boost::tuple<YASP_2D_EQUIDISTANT_OFFSET
+#if HAVE_DUNE_ALUGRID
+                                                   ,
+                                                   ALU_2D_SIMPLEX_CONFORMING
+#endif
+                                                   >>::bind(m);
+} // PYBIND11_MODULE(...)
diff --git a/python/dune/xt/functions/interfaces/grid-function_3d.cc b/python/dune/xt/functions/interfaces/grid-function_3d.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d1d5a73c288a882ba5527eeb6edfd058e8c2d458
--- /dev/null
+++ b/python/dune/xt/functions/interfaces/grid-function_3d.cc
@@ -0,0 +1,31 @@
+// This file is part of the dune-xt project:
+//   https://github.com/dune-community/dune-xt
+// Copyright 2009-2018 dune-xt developers and contributors. All rights reserved.
+// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
+//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
+//          with "runtime exception" (http://www.dune-project.org/license.html)
+// Authors:
+//   Felix Schindler (2020)
+
+#include "config.h"
+
+#include <dune/xt/grid/grids.hh>
+
+#include "grid-function_for_all_grids.hh"
+
+
+PYBIND11_MODULE(_functions_interfaces_grid_function_3d, m)
+{
+  namespace py = pybind11;
+
+  py::module::import("dune.xt.common");
+  py::module::import("dune.xt.grid");
+  py::module::import("dune.xt.la");
+
+  GridFunctionInterface_for_all_grids<boost::tuple<YASP_3D_EQUIDISTANT_OFFSET
+#if HAVE_DUNE_ALUGRID
+                                                   ,
+                                                   ALU_3D_SIMPLEX_CONFORMING
+#endif
+                                                   >>::bind(m);
+} // PYBIND11_MODULE(...)
diff --git a/python/dune/xt/functions/interfaces/grid-function_for_all_grids.hh b/python/dune/xt/functions/interfaces/grid-function_for_all_grids.hh
new file mode 100644
index 0000000000000000000000000000000000000000..b30747493af3fb987106be76fa98b166e9fea1fe
--- /dev/null
+++ b/python/dune/xt/functions/interfaces/grid-function_for_all_grids.hh
@@ -0,0 +1,121 @@
+// This file is part of the dune-xt project:
+//   https://github.com/dune-community/dune-xt
+// Copyright 2009-2018 dune-xt developers and contributors. All rights reserved.
+// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
+//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
+//          with "runtime exception" (http://www.dune-project.org/license.html)
+// Authors:
+//   Felix Schindler (2020)
+
+#ifndef PYTHON_DUNE_XT_FUNCTIONS_INTERFACES_GRID_FUNCTION_FOR_ALL_GRIDS_HH
+#define PYTHON_DUNE_XT_FUNCTIONS_INTERFACES_GRID_FUNCTION_FOR_ALL_GRIDS_HH
+
+#include <dune/xt/grid/type_traits.hh>
+
+#include <python/dune/xt/functions/base/combined-grid-function.hh>
+
+#include "grid-function.hh"
+
+
+template <size_t ii>
+struct Int
+{
+  static const constexpr size_t value = ii;
+};
+
+
+template <class GridTypes>
+struct GridFunctionInterface_for_all_grids
+{
+  using G = typename GridTypes::head_type;
+  using GV = typename G::LeafGridView;
+  using E = Dune::XT::Grid::extract_entity_t<GV>;
+  static const constexpr size_t d = G::dimension;
+
+  template <size_t r, class Dims = boost::tuple<Int<1>, Int<2>, Int<3>>>
+  struct for_all_rC
+  {
+    static const constexpr size_t rC = Dims::head_type::value;
+
+    template <bool scalar = (r == 1 && rC == 1), bool anything = true>
+    struct fraction_helper
+    {
+      static void addbind(pybind11::module& m)
+      {
+        using Dune::XT::Functions::bindings::FractionGridFunction;
+        using Dune::XT::Grid::bindings::grid_name;
+
+        FractionGridFunction<G, E>::bind(m, grid_name<G>::value());
+      }
+    };
+
+    template <bool a>
+    struct fraction_helper<false, a>
+    {
+      static void addbind(pybind11::module& /*m*/) {}
+    };
+
+    static void bind(pybind11::module& m)
+    {
+      using Dune::XT::Functions::bindings::DifferenceGridFunction;
+      using Dune::XT::Functions::bindings::GridFunctionInterface;
+      using Dune::XT::Functions::bindings::ProductGridFunction;
+      using Dune::XT::Functions::bindings::SumGridFunction;
+      using Dune::XT::Grid::bindings::grid_name;
+
+      GridFunctionInterface<G, E, r, rC>::bind(m, grid_name<G>::value());
+      DifferenceGridFunction<G, E, r, rC>::bind(m, grid_name<G>::value());
+      SumGridFunction<G, E, r, rC>::bind(m, grid_name<G>::value());
+      ProductGridFunction<G, E, r, rC>::bind(m, grid_name<G>::value());
+      fraction_helper<>::addbind(m);
+
+      for_all_rC<r, typename Dims::tail_type>::bind(m);
+    }
+  };
+
+  template <size_t r>
+  struct for_all_rC<r, boost::tuples::null_type>
+  {
+    static void bind(pybind11::module& /*m*/) {}
+  };
+
+
+  template <class Dims = boost::tuple<Int<1>, Int<2>, Int<3>>, bool anything = false>
+  struct for_all_r_and_rC
+  {
+    static const constexpr size_t r = Dims::head_type::value;
+
+    static void bind(pybind11::module& m)
+    {
+      for_all_rC<r>::bind(m);
+
+      for_all_r_and_rC<typename Dims::tail_type>::bind(m);
+    }
+  };
+
+  template <bool a>
+  struct for_all_r_and_rC<boost::tuples::null_type, a>
+  {
+    static void bind(pybind11::module& /*m*/) {}
+  };
+
+
+  static void bind(pybind11::module& m)
+  {
+    using Dune::XT::Functions::bindings::FractionGridFunction;
+    using Dune::XT::Grid::bindings::grid_name;
+
+    for_all_r_and_rC<>::bind(m);
+
+    GridFunctionInterface_for_all_grids<typename GridTypes::tail_type>::bind(m);
+  }
+};
+
+template <>
+struct GridFunctionInterface_for_all_grids<boost::tuples::null_type>
+{
+  static void bind(pybind11::module& /*m*/) {}
+};
+
+
+#endif // PYTHON_DUNE_XT_FUNCTIONS_INTERFACES_GRID_FUNCTION_FOR_ALL_GRIDS_HH
diff --git a/python/dune/xt/functions/spe10.cc b/python/dune/xt/functions/spe10.cc
index e451c4881bb7368356a84267ee67a8ab51b27429..f83009d4ac5501ff126d1162b154df26f0406320 100644
--- a/python/dune/xt/functions/spe10.cc
+++ b/python/dune/xt/functions/spe10.cc
@@ -60,9 +60,9 @@ PYBIND11_MODULE(_functions_spe10, m)
   py::module::import("dune.xt.common");
   py::module::import("dune.xt.la");
   py::module::import("dune.xt.grid");
-  py::module::import("dune.xt.functions._functions_gridfunction_interface_1d");
-  py::module::import("dune.xt.functions._functions_gridfunction_interface_2d");
-  py::module::import("dune.xt.functions._functions_gridfunction_interface_3d");
+  py::module::import("dune.xt.functions._functions_interfaces_grid_function_1d");
+  py::module::import("dune.xt.functions._functions_interfaces_grid_function_2d");
+  py::module::import("dune.xt.functions._functions_interfaces_grid_function_3d");
 
   all_grids(m);
 }