diff --git a/dumux/python/common/boundarytypes.hh b/dumux/python/common/boundarytypes.hh
index 460ca8a155352fb7e678bcef254b92fc7f91a1b2..6a423610a3f5e44a2ffe5bee1f304751d28ad5dc 100644
--- a/dumux/python/common/boundarytypes.hh
+++ b/dumux/python/common/boundarytypes.hh
@@ -41,8 +41,8 @@ void registerBoundaryTypes(pybind11::handle scope, pybind11::class_<BoundaryType
     cls.def("reset", &BoundaryTypes::reset);
     cls.def("setNeumann", &BoundaryTypes::setAllNeumann);
     cls.def("setDirichlet", &BoundaryTypes::setAllDirichlet);
-    cls.def("isDirichlet", &BoundaryTypes::hasDirichlet);
-    cls.def("isNeumann", &BoundaryTypes::hasNeumann);
+    cls.def_property_readonly("isDirichlet", &BoundaryTypes::hasDirichlet);
+    cls.def_property_readonly("isNeumann", &BoundaryTypes::hasNeumann);
 }
 
 template <class BoundaryTypes>
diff --git a/dumux/python/common/fvproblem.hh b/dumux/python/common/fvproblem.hh
index d4f9c8285cafd962fa423132128d1df865e5cb58..21e6904314289d94844d44cfc21ef630f9b54422 100644
--- a/dumux/python/common/fvproblem.hh
+++ b/dumux/python/common/fvproblem.hh
@@ -239,6 +239,7 @@ void registerFVProblem(pybind11::handle scope, pybind11::class_<Problem, options
 
     cls.def_property_readonly("name", &Problem::name);
     cls.def_property_readonly("numEq", [](Problem&){ return Problem::numEq; });
+    cls.def_property_readonly("gridGeometry", &Problem::gridGeometry);
 
     using GridView = typename GridGeometry::GridView;
     using Element = typename GridView::template Codim<0>::Entity;
@@ -263,7 +264,6 @@ void registerFVProblem(pybind11::handle scope, pybind11::class_<Problem, options
     cls.def("initial", &Problem::template initial<Element>);
     cls.def("initial", &Problem::template initial<Vertex>);
     cls.def("extrusionFactor", &Problem::template extrusionFactor<decltype(std::ignore)>);
-    cls.def("gridGeometry", &Problem::gridGeometry);
 }
 
 } // end namespace Dumux::Python
diff --git a/dumux/python/common/timeloop.hh b/dumux/python/common/timeloop.hh
index 9117c0ee48fd13557549fc2eb1385e3a407ebbb0..241150807d029e51f12a13f574d15a7d9d27b4c7 100644
--- a/dumux/python/common/timeloop.hh
+++ b/dumux/python/common/timeloop.hh
@@ -42,18 +42,18 @@ void registerTimeLoop(pybind11::handle scope,
         return new TimeLoop(startTime, dt, endTime, verbose);
     }), "startTime"_a, "dt"_a, "endTime"_a, "verbose"_a=true);
 
-    cls.def("time", &TimeLoop::time);
-    cls.def("timeStepSize", &TimeLoop::timeStepSize);
+    cls.def_property_readonly("time", &TimeLoop::time);
+    cls.def_property_readonly("timeStepSize", &TimeLoop::timeStepSize);
+    cls.def_property_readonly("finished", &TimeLoop::finished);
+    cls.def_property_readonly("isCheckPoint", &TimeLoop::isCheckPoint);
     cls.def("start", &TimeLoop::start);
     cls.def("reset", &TimeLoop::reset, "startTime"_a, "dt"_a, "endTime"_a, "verbose"_a=true);
     cls.def("advanceTimeStep", &TimeLoop::advanceTimeStep);
     cls.def("setTimeStepSize", &TimeLoop::setTimeStepSize, "dt"_a);
     cls.def("setMaxTimeStepSize", &TimeLoop::setMaxTimeStepSize, "dt"_a);
-    cls.def("finished", &TimeLoop::finished);
     cls.def("reportTimeStep", &TimeLoop::reportTimeStep);
     cls.def("finalize", [](TimeLoop& self){ self.finalize(); });
     cls.def("setPeriodicCheckPoint", &TimeLoop::setPeriodicCheckPoint, "interval"_a, "offset"_a=0.0);
-    cls.def("isCheckPoint", &TimeLoop::isCheckPoint);
     cls.def("setCheckPoints", [](TimeLoop& self, const std::vector<double>& checkPoints) {
         self.setCheckPoint(checkPoints);
     });
diff --git a/dumux/python/discretization/gridgeometry.hh b/dumux/python/discretization/gridgeometry.hh
index 0c9ab5261589a7af23777114811188e61f901e3d..6b523fa6ec40d53806b46fdf9dcf5985da1a41b1 100644
--- a/dumux/python/discretization/gridgeometry.hh
+++ b/dumux/python/discretization/gridgeometry.hh
@@ -103,11 +103,11 @@ void registerFVElementGeometry(pybind11::handle scope)
         cls.def_property_readonly("numScv", &FVEG::numScv);
         cls.def_property_readonly("hasBoundaryScvf", &FVEG::hasBoundaryScvf);
         cls.def("bind", &FVEG::bind, "element"_a);
-        cls.def("scvs", [](FVEG& self){
+        cls.def_property_readonly("scvs", [](FVEG& self){
             const auto range = scvs(self);
             return pybind11::make_iterator(range.begin(), range.end());
         }, pybind11::keep_alive<0, 1>());
-        cls.def("scvfs", [](FVEG& self){
+        cls.def_property_readonly("scvfs", [](FVEG& self){
             const auto range = scvfs(self);
             return pybind11::make_iterator(range.begin(), range.end());
         }, pybind11::keep_alive<0, 1>());
@@ -147,6 +147,8 @@ void registerGridGeometry(pybind11::handle scope, pybind11::class_<GG, Options..
         return toString(GG::discMethod);
     });
 
+    cls.def_property_readonly("localView", [](GG& self){ return localView(self); });
+
     using SubControlVolume = typename GG::SubControlVolume;
     Impl::registerSubControlVolume<SubControlVolume>(scope);
 
@@ -156,8 +158,7 @@ void registerGridGeometry(pybind11::handle scope, pybind11::class_<GG, Options..
     // also compile the corresponding local view
     using LocalView = typename GG::LocalView;
     Impl::registerFVElementGeometry<LocalView>(scope);
-    // and make it accessible
-    cls.def("localView", [](GG& self){ return localView(self); });
+
 }
 
 } // namespace Dumux::Python
diff --git a/dumux/python/material/components/component.hh b/dumux/python/material/components/component.hh
index 288e867d1c7ab6d3488b4d4fdc35f5a9492234e0..9ad1b1ca87ce468bbf2cb32ed8b476cc4a7c11a1 100644
--- a/dumux/python/material/components/component.hh
+++ b/dumux/python/material/components/component.hh
@@ -18,14 +18,14 @@ void registerComponent(pybind11::handle scope,
 
     cls.def(pybind11::init());
 
-    cls.def_static("name", &Comp::name);
-    cls.def_static("molarMass", &Comp::molarMass);
+    cls.def_property_readonly_static("name", &Comp::name);
+    cls.def_property_readonly_static("molarMass", &Comp::molarMass);
 
     if constexpr (ComponentTraits<Comp>::hasLiquidState)
     {
         cls.def_static("liquidDensity", &Comp::liquidDensity, "temperature"_a, "pressure"_a);
         cls.def_static("liquidMolarDensity", &Comp::liquidMolarDensity, "temperature"_a, "pressure"_a);
-        cls.def_static("liquidIsCompressible", &Comp::liquidIsCompressible);
+        cls.def_property_readonly_static("liquidIsCompressible", &Comp::liquidIsCompressible);
         cls.def_static("liquidViscosity", &Comp::liquidViscosity, "temperature"_a, "pressure"_a);
         cls.def_static("liquidEnthalpy", &Comp::liquidEnthalpy, "temperature"_a, "pressure"_a);
         cls.def_static("liquidInternalEnergy", &Comp::liquidInternalEnergy, "temperature"_a, "pressure"_a);
@@ -39,8 +39,8 @@ void registerComponent(pybind11::handle scope,
         using Scalar = typename Comp::Scalar;
         cls.def_static("gasDensity", &Comp::gasDensity, "temperature"_a, "pressure"_a);
         cls.def_static("gasMolarDensity", &Comp::gasMolarDensity, "temperature"_a, "pressure"_a);
-        cls.def_static("gasIsCompressible", &Comp::gasIsCompressible);
-        cls.def_static("gasIsIdeal", &Comp::gasIsIdeal);
+        cls.def_property_readonly_static("gasIsCompressible", &Comp::gasIsCompressible);
+        cls.def_property_readonly_static("gasIsIdeal", &Comp::gasIsIdeal);
         cls.def_static("gasPressure", &Comp::gasPressure, "temperature"_a, "pressure"_a);
         cls.def_static("gasViscosity", &Comp::gasViscosity, "temperature"_a, "pressure"_a);
         cls.def_static("gasEnthalpy", &Comp::gasEnthalpy, "temperature"_a, "pressure"_a);
@@ -51,7 +51,7 @@ void registerComponent(pybind11::handle scope,
 
     if constexpr (ComponentTraits<Comp>::hasSolidState)
     {
-        cls.def_static("solidIsCompressible", &Comp::solidIsCompressible);
+        cls.def_property_readonly_static("solidIsCompressible", &Comp::solidIsCompressible);
         cls.def_static("solidDensity", &Comp::solidDensity, "temperature_a");
         cls.def_static("solidThermalConductivity", &Comp::solidThermalConductivity, "temperature_a");
         cls.def_static("solidHeatCapacity", &Comp::solidHeatCapacity, "temperature_a");
@@ -59,13 +59,13 @@ void registerComponent(pybind11::handle scope,
 
     if constexpr (ComponentTraits<Comp>::isIon)
     {
-        cls.def_static("charge", &Comp::charge);
+        cls.def_property_readonly_static("charge", &Comp::charge);
     }
 
     if constexpr (ComponentTraits<Comp>::hasLiquidState || ComponentTraits<Comp>::hasGasState)
     {
-        cls.def_static("criticalTemperature", &Comp::criticalTemperature);
-        cls.def_static("criticalPressure", &Comp::criticalPressure);
+        cls.def_property_readonly_static("criticalTemperature", &Comp::criticalTemperature);
+        cls.def_property_readonly_static("criticalPressure", &Comp::criticalPressure);
     }
 }
 
diff --git a/test/python/test_explicit_transport_cctpfa.py b/test/python/test_explicit_transport_cctpfa.py
index beb2f03dc37a89b0534fdfde7b373ed39f79f7a2..bf2e26872f6a3fa019701ef0a237a8262cf43b85 100755
--- a/test/python/test_explicit_transport_cctpfa.py
+++ b/test/python/test_explicit_transport_cctpfa.py
@@ -46,7 +46,7 @@ class Problem:
         return bTypes
 
     def dirichlet(self, element, scvf):
-        if scvf.ipGlobal().two_norm < 0.25:
+        if scvf.ipGlobal.two_norm < 0.25:
             return 1.0
         else:
             return 0.0
@@ -79,7 +79,7 @@ def advectiveFlux(insideConcentration, outsideConcentration, normal):
 # Define solution vector #
 ##########################
 
-solution = np.zeros(gridGeometry.numDofs())
+solution = np.zeros(gridGeometry.numDofs)
 
 
 ###################
@@ -119,36 +119,38 @@ plot(time=0)
 # Implement update #
 ####################
 
+
 def assembleUpdate():
-    update = np.zeros(gridGeometry.numDofs())
+    update = np.zeros(gridGeometry.numDofs)
 
     for element in gridView.elements:
-        fvGeometry = gridGeometry.localView()
+        fvGeometry = gridGeometry.localView
         fvGeometry.bind(element)
 
-        for scvf in fvGeometry.scvfs():
-            insideScvIdx = scvf.insideScvIdx()
+        for scvf in fvGeometry.scvfs:
+            insideScvIdx = scvf.insideScvIdx
             insideConcentration = solution[insideScvIdx]
 
-            if scvf.boundary():
+            if scvf.boundary:
                 bndType = problem.boundaryTypes(element, scvf)
-                if bndType.isDirichlet():
+                if bndType.isDirichlet:
                     outsideConcentration = problem.dirichlet(element, scvf)[0]
                 else:
-                    raise Exception('Only Dirichlet BCs are implemented!')
+                    raise Exception("Only Dirichlet BCs are implemented!")
 
             else:
-                outsideScvIdx = scvf.outsideScvIdx()
+                outsideScvIdx = scvf.outsideScvIdx
                 outsideConcentration = solution[outsideScvIdx]
 
-            flux = advectiveFlux(insideConcentration,
-                                 outsideConcentration,
-                                 scvf.unitOuterNormal())*scvf.area()
+            flux = (
+                advectiveFlux(insideConcentration, outsideConcentration, scvf.unitOuterNormal)
+                * scvf.area
+            )
 
             update[insideScvIdx] -= flux
 
-        for scv in fvGeometry.scvs():
-            update[scv.dofIndex()] /= scv.volume()
+        for scv in fvGeometry.scvs:
+            update[scv.dofIndex] /= scv.volume
 
     return update
 
@@ -162,13 +164,13 @@ timeLoop = TimeLoop(startTime=0.0, dt=dt, endTime=1.0, verbose=True)
 timeLoop.setPeriodicCheckPoint(0.25)
 
 timeLoop.start()
-while not timeLoop.finished():
+while not timeLoop.finished:
     update = assembleUpdate()
-    solution += timeLoop.timeStepSize() * update
+    solution += timeLoop.timeStepSize * update
     timeLoop.advanceTimeStep()
     timeLoop.reportTimeStep()
 
-    if timeLoop.isCheckPoint():
-        plot(time=timeLoop.time())
+    if timeLoop.isCheckPoint:
+        plot(time=timeLoop.time)
 
 timeLoop.finalize()
diff --git a/test/python/test_fvproblem.py b/test/python/test_fvproblem.py
index 95b9e22f532d5c34b663e08a719bb140a1dd893a..26b41d0f7519d7cd92d30e1d46d15b7af5e84e6c 100644
--- a/test/python/test_fvproblem.py
+++ b/test/python/test_fvproblem.py
@@ -38,7 +38,7 @@ class Problem:
         return bTypes
 
     def dirichlet(self, element, scv):
-        if scv.center()[0] > 0.5:
+        if scv.center[0] > 0.5:
             return [0.5, 0.5]
         else:
             return [1.0, 0.0]
@@ -62,15 +62,15 @@ numNeumann = 0
 numDirichlet = 0
 totalSource = 0
 for e in gridView.elements:
-    fvGeometry = problem.gridGeometry().localView()
+    fvGeometry = problem.gridGeometry.localView  # test problem interface
     fvGeometry.bind(e)
-    for scv in fvGeometry.scvs():
+    for scv in fvGeometry.scvs:
         bTypes = problem.boundaryTypes(element=e, scv=scv)
-        if bTypes.isDirichlet():
+        if bTypes.isDirichlet:
             numDirichlet += 1
-        elif bTypes.isNeumann():
+        elif bTypes.isNeumann:
             numNeumann += 1
-        totalSource += problem.sourceAtPos(scv.center())[0]*scv.volume()
+        totalSource += problem.sourceAtPos(scv.center)[0] * scv.volume
 
-print("[python] Found {} Neumann faces and {} Dirichlet faces".format(numNeumann, numDirichlet))
-print("[python] Total source {:.2f} kg/s".format(totalSource))
+print(f"[python] Found {numNeumann} Neumann faces and {numDirichlet} Dirichlet faces")
+print(f"[python] Total source {totalSource:.2f} kg/s")
diff --git a/test/python/test_gridgeometry.py b/test/python/test_gridgeometry.py
index 409f57115e8b99ab8fd96a5f643ef494be81b7b9..7d7fa8e2d143aa746c29be86771f2f72500ac252 100755
--- a/test/python/test_gridgeometry.py
+++ b/test/python/test_gridgeometry.py
@@ -3,18 +3,18 @@
 from dune.grid import structuredGrid
 from dumux.discretization import GridGeometry
 
-gridView = structuredGrid([0,0],[1,1],[5,5])
+gridView = structuredGrid([0, 0], [1, 1], [5, 5])
 
 gridGeometry = GridGeometry(gridView, discMethod="cctpfa")
 
-print("The total number of scvs is {}".format(gridGeometry.numScv()))
-print("The total number of scvfs is {}".format(gridGeometry.numScvf()))
+print("The total number of scvs is {}".format(gridGeometry.numScv))
+print("The total number of scvfs is {}".format(gridGeometry.numScvf))
 
 for e in gridView.elements:
-    fvGeometry = gridGeometry.localView()
+    fvGeometry = gridGeometry.localView
     fvGeometry.bind(e)
 
-    for scv in fvGeometry.scvs():
-        print("scv dofIndex: {}".format(scv.dofIndex()))
-        print("scv center: {}".format(scv.center()))
-        print("scv volume: {}".format(scv.volume()))
+    for scv in fvGeometry.scvs:
+        print(f"scv dofIndex: {scv.dofIndex}")
+        print(f"scv center: {scv.center}")
+        print(f"scv volume: {scv.volume}")