OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

Python class is instantiated with a @classmethod but it is erroring that too many arguments are being passed to the classes __init__ method

  • Thread starter Thread starter Rory MacGegor
  • Start date Start date
R

Rory MacGegor

Guest
As stated in the title, I have a class called TestLandCover which won't instantiate using the from_geotiff @classmethod because it supposedly only takes 1 positional argument. However, the init method takes 6 arguments.

Here is the class:

Code:
import rasterio
from rasterio.mask import mask


class TestLandCover():
    def __init__(self, raster, transform, crs, name, nodata):
        self.raster = raster
        self.transform = transform
        self.crs = crs
        self.name = name
        self.nodata = nodata
    
    @classmethod
    def from_geotiff(cls, geotiff_path, name=None, nodata=np.nan, mask_gdf=None):
        
        with rasterio.open(geotiff_path) as src:
            crs = src.crs
            print(f'CRS line 418: {crs}')
            transform = src.transform

            if mask_gdf is not None:
                if 'geometry' in mask_gdf:
                    geometries = mask_gdf.geometry.tolist()
                else:
                    raise ValueError("The provided GeoDataFrame does not have a 'geometry' column.")
                
                # Mask the raster data using the provided geometries
                data, out_trans = mask(src, geometries, crop=True, nodata=nodata)
                
                # Ensure data is in a 2D array format (first band)
                data = data[0]
            else:
                data = src.read(1)
                out_trans = transform

        return cls(data, out_trans, crs, name, nodata)

However when I instantiate the class like this:

Code:
landcover_test = TestLandCover.from_geotiff(geotiff_path='input_data/NELandcover/ukregion-northeastengland.tif', mask_gdf=area_of_interst.gdf, nodata=0, name='landcover_test')

I am receiving this error:

Code:
Traceback (most recent call last):
  File "c:\proj\ecosys-oppo-model\model.py", line 432, in <module>
    landcover_test = TestLandCover.from_geotiff(geotiff_path='input_data/NELandcover/ukregion-northeastengland.tif', mask_gdf=area_of_interst.gdf, nodata=0, name='landcover_test')
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\proj\ecosys-oppo-model\classes.py", line 670, in from_geotiff
    return cls(data, out_trans, crs, name, nodata)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: TestLandCover.__init__() takes 1 positional argument but 6 were given

This problem arose after I refactored some code and interestingly, the old parent class which TestLandCover used to inherit from which has the same from_geotiff @classmethod does instatntiate correctly:

Code:
class RasterData(DataLayer):
    def __init__(self, raster=None, transform=None, crs=None, nodata=None, name=None):
        print(f'Initializing RasterData with raster={raster}, transform={transform}, crs={crs}, nodata={nodata}, name={name}')
        #super().__init__()
        self.raster = raster
        self.transform = transform
        self.crs = crs
        self.nodata = nodata
        self.name = name

    @classmethod
    def from_geotiff(cls, geotiff_path, name=None, nodata=np.nan, mask_gdf=None):
        
        with rasterio.open(geotiff_path) as src:
            crs = src.crs
            print(f'CRS line 418: {crs}')
            transform = src.transform
            print(f'Transform line 420: {transform}')

            if mask_gdf is not None:
                if 'geometry' in mask_gdf:
                    geometries = mask_gdf.geometry.tolist()
                else:
                    raise ValueError("The provided GeoDataFrame does not have a 'geometry' column.")
                
                # Mask the raster data using the provided geometries
                data, out_trans = mask(src, geometries, crop=True, nodata=nodata)
                print(f'out_trans: {out_trans}')
                
                # Ensure data is in a 2D array format (first band)
                data = data[0]
            else:
                data = src.read(1)
                out_trans = transform

        return cls(raster=data, transform=out_trans, crs=crs, name=name, nodata=nodata)

I can't see any reason why that would work and yet the TestLandCover wouldn't. To instantiate it I am just swapping out the TestLandCover for RasterData. RasterData works, TestLandCover doesn't.

I'm beginning to think this is a bug but would appreciate anyone else's input.

Also I have discovered that if I just define the lass in the Python 2 style like

Code:
class TestLandCover:
    def __init__(self, raster, transform, crs, name, nodata):
        self.raster = raster
        self.transform = transform
        self.crs = crs
        self.name = name
        self.nodata = nodata

It works but I don't see why and I do want the class to inherit from RasterData which If I set up it doesn't work again.
<p>As stated in the title, I have a class called TestLandCover which won't instantiate using the from_geotiff @classmethod because it supposedly only takes 1 positional argument. However, the <strong>init</strong> method takes 6 arguments.</p>
<p>Here is the class:</p>
<pre><code>import rasterio
from rasterio.mask import mask


class TestLandCover():
def __init__(self, raster, transform, crs, name, nodata):
self.raster = raster
self.transform = transform
self.crs = crs
self.name = name
self.nodata = nodata

@classmethod
def from_geotiff(cls, geotiff_path, name=None, nodata=np.nan, mask_gdf=None):

with rasterio.open(geotiff_path) as src:
crs = src.crs
print(f'CRS line 418: {crs}')
transform = src.transform

if mask_gdf is not None:
if 'geometry' in mask_gdf:
geometries = mask_gdf.geometry.tolist()
else:
raise ValueError("The provided GeoDataFrame does not have a 'geometry' column.")

# Mask the raster data using the provided geometries
data, out_trans = mask(src, geometries, crop=True, nodata=nodata)

# Ensure data is in a 2D array format (first band)
data = data[0]
else:
data = src.read(1)
out_trans = transform

return cls(data, out_trans, crs, name, nodata)
</code></pre>
<p>However when I instantiate the class like this:</p>
<pre><code>landcover_test = TestLandCover.from_geotiff(geotiff_path='input_data/NELandcover/ukregion-northeastengland.tif', mask_gdf=area_of_interst.gdf, nodata=0, name='landcover_test')
</code></pre>
<p>I am receiving this error:</p>
<pre><code>Traceback (most recent call last):
File "c:\proj\ecosys-oppo-model\model.py", line 432, in <module>
landcover_test = TestLandCover.from_geotiff(geotiff_path='input_data/NELandcover/ukregion-northeastengland.tif', mask_gdf=area_of_interst.gdf, nodata=0, name='landcover_test')
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\proj\ecosys-oppo-model\classes.py", line 670, in from_geotiff
return cls(data, out_trans, crs, name, nodata)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: TestLandCover.__init__() takes 1 positional argument but 6 were given
</code></pre>
<p>This problem arose after I refactored some code and interestingly, the old parent class which TestLandCover used to inherit from which has the same from_geotiff @classmethod does instatntiate correctly:</p>
<pre><code>class RasterData(DataLayer):
def __init__(self, raster=None, transform=None, crs=None, nodata=None, name=None):
print(f'Initializing RasterData with raster={raster}, transform={transform}, crs={crs}, nodata={nodata}, name={name}')
#super().__init__()
self.raster = raster
self.transform = transform
self.crs = crs
self.nodata = nodata
self.name = name

@classmethod
def from_geotiff(cls, geotiff_path, name=None, nodata=np.nan, mask_gdf=None):

with rasterio.open(geotiff_path) as src:
crs = src.crs
print(f'CRS line 418: {crs}')
transform = src.transform
print(f'Transform line 420: {transform}')

if mask_gdf is not None:
if 'geometry' in mask_gdf:
geometries = mask_gdf.geometry.tolist()
else:
raise ValueError("The provided GeoDataFrame does not have a 'geometry' column.")

# Mask the raster data using the provided geometries
data, out_trans = mask(src, geometries, crop=True, nodata=nodata)
print(f'out_trans: {out_trans}')

# Ensure data is in a 2D array format (first band)
data = data[0]
else:
data = src.read(1)
out_trans = transform

return cls(raster=data, transform=out_trans, crs=crs, name=name, nodata=nodata)
</code></pre>
<p>I can't see any reason why that would work and yet the TestLandCover wouldn't. To instantiate it I am just swapping out the TestLandCover for RasterData. RasterData works, TestLandCover doesn't.</p>
<p>I'm beginning to think this is a bug but would appreciate anyone else's input.</p>
<p>Also I have discovered that if I just define the lass in the Python 2 style like</p>
<pre><code>class TestLandCover:
def __init__(self, raster, transform, crs, name, nodata):
self.raster = raster
self.transform = transform
self.crs = crs
self.name = name
self.nodata = nodata
</code></pre>
<p>It works but I don't see why and I do want the class to inherit from RasterData which If I set up it doesn't work again.</p>
 

Latest posts

Top