3

I would like to create a subclass that inherits methods from the arcpy Describe class, as in:

import arcpy

class my_sublass(arcpy.Describe):
    pass

However, arcpy.Describe is a function (that returns a class object, according to ESRI), not a class in and of itself. How can I code my_subclass such that it inherits from the Describe class?

For reference, I am in Python 3, using a cloned environment from Pro's default conda distribution.

5

I don't think you can. If you dig into the arcpy source you'll find that arcpy.Describe essentially returns a wrapper around a non-python binary object (see line 369 in <install dir>\ArcGIS\Pro\Resources\ArcPy\arcpy\geoprocessing\_base.py) which doesn't have a class you can inherit from.

However, you could fake a subclass, by creating a stand-alone class that:

  • in __init__, accepts a value to describe then creates and stores the describe instance
  • defines any custom properties or methods you want
  • automatically passes through any attempts to access Describe object properties to the real describe instance and returns the result using a __getattr__ method.

A simple example:

import arcpy


class CustomDescribe(object):

    def __init__(self, thing):
        self._desc = arcpy.Describe(thing)
        self.test_value = 'Hello'

    def __getattr__(self, attr):
        """Pass any other attribute or method calls through to the underlying Describe object"""
        return getattr(self._desc, attr)

    def test_method(self):
        return 'World!'


a = CustomDescribe(r'C:\temp\Default.gdb')

print(a.datatype)
print(a.test_value)
print(a.test_method())
Workspace
Hello
World!
  • I'm just learning about coding with classes, and this seems wonderfully sneaky. I think I understand the logic of __getattr__: it's kind of synthesizing the class tree lookup without directly inheriting attributes of Describe, right? Is that what you mean by "faking" it? Also, why the leading underscore for self._desc? – jesnes Sep 24 at 3:57
  • Yes, any call to a property or method that isn't explicitly defined by your class will get passed automatically to __getattr__ (if you define a __getattr__ method). It's not a subclass of Describe, it's just pretending to be, so it's "faking it". The underscore prefix is a hint to programmers/IDEs/code analysers etc.. that a variable or method is intended for internal use, i.e it's private. This convention is defined in PEP 8, though python doesn't enforce it. – user2856 Sep 24 at 5:51
  • 1
    Ah, now that I'm looking through arcpy source, I see tons of those leading underscores. Why would ESRI code their software like this? Is there an inherent advantage to structuring fake inheritance in this way? – jesnes Sep 24 at 13:32
  • Not sure what you mean. Whether a variable is supposed to be private/internal has nothing to do with what I called faking a subclass. The issue with Describe and other objects that arcpy wraps is that they have no class to inherit from, they're just an interface to non-python objects, kind of like what SWIG does en.m.wikipedia.org/wiki/SWIG – user2856 Sep 24 at 20:24
  • 1
    Oh, because an ArcObject isn't a Python class! Ok, I get it. Thank you for your help, this has been educational in the extreme. – jesnes Sep 24 at 21:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.