<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>idea arcpy.List[Type] functions: Let us feed it a workspace instead of having to switch the environment in Python Ideas</title>
    <link>https://community.esri.com/t5/python-ideas/arcpy-list-type-functions-let-us-feed-it-a/idi-p/1529687</link>
    <description>&lt;BLOCKQUOTE&gt;&lt;P&gt;&lt;SPAN&gt;The workspace environment must be set before using several of the list functions, including&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN class=""&gt;&lt;A href="https://pro.arcgis.com/en/pro-app/3.3/arcpy/functions/listdatasets.htm" target="_blank" rel="noopener"&gt;ListDatasets&lt;/A&gt;&lt;/SPAN&gt;&lt;SPAN&gt;,&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN class=""&gt;&lt;A href="https://pro.arcgis.com/en/pro-app/3.3/arcpy/functions/listfeatureclasses.htm" target="_blank" rel="noopener"&gt;ListFeatureClasses&lt;/A&gt;&lt;/SPAN&gt;&lt;SPAN&gt;,&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN class=""&gt;&lt;A href="https://pro.arcgis.com/en/pro-app/3.3/arcpy/functions/listfiles.htm" target="_blank" rel="noopener"&gt;ListFiles&lt;/A&gt;&lt;/SPAN&gt;&lt;SPAN&gt;,&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN class=""&gt;&lt;A href="https://pro.arcgis.com/en/pro-app/3.3/arcpy/functions/listrasters.htm" target="_blank" rel="noopener"&gt;ListRasters&lt;/A&gt;&lt;/SPAN&gt;&lt;SPAN&gt;,&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN class=""&gt;&lt;A href="https://pro.arcgis.com/en/pro-app/3.3/arcpy/functions/listtables.htm" target="_blank" rel="noopener"&gt;ListTables&lt;/A&gt;&lt;/SPAN&gt;&lt;SPAN&gt;, and&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN class=""&gt;&lt;A href="https://pro.arcgis.com/en/pro-app/3.3/arcpy/functions/listworkspaces.htm" target="_blank" rel="noopener"&gt;ListWorkspaces&lt;/A&gt;&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;It is super, super annoying to use the arcpy.ListFeatureClasses, ...Tables, etc. functions right now because you can't specify a workspace you're checking.&lt;/P&gt;&lt;P&gt;Instead, you have to set the environment to that workspace, first.&lt;/P&gt;&lt;PRE&gt;arcpy.env.workspace = "whatever.gdb"&lt;BR /&gt;for tab in arcpy.ListTables():&lt;BR /&gt;    print(tab.name)&lt;/PRE&gt;&lt;P&gt;I would love, love, LOVE if we didn't have to do all that and could just feed it the workspace directly.&lt;/P&gt;&lt;P&gt;Right now, the call for List FeatureClasses, (for example) is as &lt;A href="https://pro.arcgis.com/en/pro-app/latest/arcpy/functions/listfeatureclasses.htm" target="_blank" rel="noopener"&gt;follows&amp;nbsp;&lt;/A&gt;:&lt;/P&gt;&lt;PRE&gt;&lt;STRONG&gt;ListFeatureClasses ({wild_card}, {feature_type}, {feature_dataset})&lt;/STRONG&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;Could we please change it to&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;ListFeatureClasses ({wild_card}, 
                    {feature_type}, 
                    {feature_dataset}, 
                    {workspace = arcpy.env.workspace}
)&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;That is, make it go to the environment workspace by default, unless you specify a different workspace?&lt;/P&gt;&lt;P&gt;I just want to be able to get a list of all the stuff for each gdb in a list without having to change the environment all the time.&lt;/P&gt;</description>
    <pubDate>Thu, 29 Aug 2024 19:09:18 GMT</pubDate>
    <dc:creator>AlfredBaldenweck</dc:creator>
    <dc:date>2024-08-29T19:09:18Z</dc:date>
    <item>
      <title>arcpy.List[Type] functions: Let us feed it a workspace instead of having to switch the environment</title>
      <link>https://community.esri.com/t5/python-ideas/arcpy-list-type-functions-let-us-feed-it-a/idi-p/1529687</link>
      <description>&lt;BLOCKQUOTE&gt;&lt;P&gt;&lt;SPAN&gt;The workspace environment must be set before using several of the list functions, including&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN class=""&gt;&lt;A href="https://pro.arcgis.com/en/pro-app/3.3/arcpy/functions/listdatasets.htm" target="_blank" rel="noopener"&gt;ListDatasets&lt;/A&gt;&lt;/SPAN&gt;&lt;SPAN&gt;,&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN class=""&gt;&lt;A href="https://pro.arcgis.com/en/pro-app/3.3/arcpy/functions/listfeatureclasses.htm" target="_blank" rel="noopener"&gt;ListFeatureClasses&lt;/A&gt;&lt;/SPAN&gt;&lt;SPAN&gt;,&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN class=""&gt;&lt;A href="https://pro.arcgis.com/en/pro-app/3.3/arcpy/functions/listfiles.htm" target="_blank" rel="noopener"&gt;ListFiles&lt;/A&gt;&lt;/SPAN&gt;&lt;SPAN&gt;,&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN class=""&gt;&lt;A href="https://pro.arcgis.com/en/pro-app/3.3/arcpy/functions/listrasters.htm" target="_blank" rel="noopener"&gt;ListRasters&lt;/A&gt;&lt;/SPAN&gt;&lt;SPAN&gt;,&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN class=""&gt;&lt;A href="https://pro.arcgis.com/en/pro-app/3.3/arcpy/functions/listtables.htm" target="_blank" rel="noopener"&gt;ListTables&lt;/A&gt;&lt;/SPAN&gt;&lt;SPAN&gt;, and&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN class=""&gt;&lt;A href="https://pro.arcgis.com/en/pro-app/3.3/arcpy/functions/listworkspaces.htm" target="_blank" rel="noopener"&gt;ListWorkspaces&lt;/A&gt;&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;It is super, super annoying to use the arcpy.ListFeatureClasses, ...Tables, etc. functions right now because you can't specify a workspace you're checking.&lt;/P&gt;&lt;P&gt;Instead, you have to set the environment to that workspace, first.&lt;/P&gt;&lt;PRE&gt;arcpy.env.workspace = "whatever.gdb"&lt;BR /&gt;for tab in arcpy.ListTables():&lt;BR /&gt;    print(tab.name)&lt;/PRE&gt;&lt;P&gt;I would love, love, LOVE if we didn't have to do all that and could just feed it the workspace directly.&lt;/P&gt;&lt;P&gt;Right now, the call for List FeatureClasses, (for example) is as &lt;A href="https://pro.arcgis.com/en/pro-app/latest/arcpy/functions/listfeatureclasses.htm" target="_blank" rel="noopener"&gt;follows&amp;nbsp;&lt;/A&gt;:&lt;/P&gt;&lt;PRE&gt;&lt;STRONG&gt;ListFeatureClasses ({wild_card}, {feature_type}, {feature_dataset})&lt;/STRONG&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;Could we please change it to&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;ListFeatureClasses ({wild_card}, 
                    {feature_type}, 
                    {feature_dataset}, 
                    {workspace = arcpy.env.workspace}
)&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;That is, make it go to the environment workspace by default, unless you specify a different workspace?&lt;/P&gt;&lt;P&gt;I just want to be able to get a list of all the stuff for each gdb in a list without having to change the environment all the time.&lt;/P&gt;</description>
      <pubDate>Thu, 29 Aug 2024 19:09:18 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-ideas/arcpy-list-type-functions-let-us-feed-it-a/idi-p/1529687</guid>
      <dc:creator>AlfredBaldenweck</dc:creator>
      <dc:date>2024-08-29T19:09:18Z</dc:date>
    </item>
    <item>
      <title>Re: arcpy.List[Type] functions: Let us feed it a workspace instead of having to switch the environment - Status changed to: Needs Clarification</title>
      <link>https://community.esri.com/t5/python-ideas/arcpy-list-type-functions-let-us-feed-it-a/idc-p/1529707#M356</link>
      <description>&lt;P&gt;Thanks for the idea!&lt;/P&gt;&lt;P&gt;From what I understand you're trying to do, the existing alternative approaches would be to use envManager to operate multiple calls against a specific GDB:&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;&lt;PRE&gt;arcpy.env.workspace = "whatever.gdb"&lt;BR /&gt;&lt;SPAN&gt;# find tables only in 'other.gdb':&lt;BR /&gt;with arcpy.EnvManager("workspace": "other.gdb"):&lt;BR /&gt;&amp;nbsp; &amp;nbsp; for table in arcpy.ListTables():&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; print(table.name)&lt;BR /&gt;&lt;BR /&gt;# reset to the global state, now get 'whatever.gdb' results&lt;BR /&gt;for table in arcpy.ListTables():&lt;BR /&gt;&amp;nbsp; &amp;nbsp; print(table.name)&lt;/SPAN&gt;&lt;/PRE&gt;&lt;P&gt;&lt;BR /&gt;The other approach you could take if you have a large collection of geodatabases to search is to use&amp;nbsp;&lt;A href="https://pro.arcgis.com/en/pro-app/latest/arcpy/data-access/walk.htm" target="_self"&gt;arcpy.da.Walk&lt;/A&gt;&amp;nbsp;instead. In that model, you'd point to some place higher up in your heirarchy that includes multiple geodatabases, then filter them as you go through the walk iterations:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;import arcpy
import os

workspace = r"C:\data"
feature_classes = {}

# can change datatype as needed to filter separate groups
walk = arcpy.da.Walk(workspace, datatype="FeatureClass")

for dirpath, dirnames, filenames in walk:
    for filename in filenames:
        if dirnames:
            last_dirname = dirnames.split(os.sep)[-1]
            if last_dirname.endswith('.gdb'):
                if last_dirname not in feature_clases:
                    feature_classes[last_dirname] = []

                feature_classes[last_dirname].append(filename)&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;Given that there are a few well supported existing paths for this, I think it would be better to try and adopt those patterns rather than the functions changing their relationship with workspaces.&lt;/P&gt;</description>
      <pubDate>Thu, 29 Aug 2024 19:50:14 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-ideas/arcpy-list-type-functions-let-us-feed-it-a/idc-p/1529707#M356</guid>
      <dc:creator>ShaunWalbridge</dc:creator>
      <dc:date>2024-08-29T19:50:14Z</dc:date>
    </item>
    <item>
      <title>Re: arcpy.List[Type] functions: Let us feed it a workspace instead of having to switch the environment</title>
      <link>https://community.esri.com/t5/python-ideas/arcpy-list-type-functions-let-us-feed-it-a/idc-p/1529762#M357</link>
      <description>&lt;P&gt;I would support the idea proposed by&amp;nbsp;&lt;a href="https://community.esri.com/t5/user/viewprofilepage/user-id/458875"&gt;@AlfredBaldenweck&lt;/a&gt;.&lt;/P&gt;&lt;P&gt;I think the idea is not to propose functionality that isn't possible, but rather to have the list functions follow a similar pattern to most other functions and have a parameter to explicitly set the workspace. It feels odd that you need to use arcpy.env.workspace (primarily) only when dealing with a list function, but not for most other things.&lt;/P&gt;</description>
      <pubDate>Thu, 29 Aug 2024 19:54:31 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-ideas/arcpy-list-type-functions-let-us-feed-it-a/idc-p/1529762#M357</guid>
      <dc:creator>BlakeTerhune</dc:creator>
      <dc:date>2024-08-29T19:54:31Z</dc:date>
    </item>
    <item>
      <title>Re: arcpy.List[Type] functions: Let us feed it a workspace instead of having to switch the environment</title>
      <link>https://community.esri.com/t5/python-ideas/arcpy-list-type-functions-let-us-feed-it-a/idc-p/1529775#M358</link>
      <description>&lt;P&gt;Yeah, Blake has the right idea.&lt;/P&gt;&lt;P&gt;For example,&amp;nbsp;&lt;A href="https://pro.arcgis.com/en/pro-app/latest/arcpy/functions/listfields.htm" target="_blank" rel="noopener"&gt;ListFields&lt;/A&gt;&amp;nbsp;takes the table that we're querying as a parameter. Why don't the other list functions do that?&lt;/P&gt;&lt;P&gt;I'm very sure that it's possible to do like&lt;/P&gt;&lt;LI-CODE lang="python"&gt;import arcpy
fgdbList = ["gdb1.gdb", "gdb2.gdb"]
for fgdb in fdbList:
    with arcpy.EnvManager(workspace=fgdb):
        feature_classes = arcpy.ListFeatureClasses(feature_type='POLYGON')&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;But why can't we just do the much more intuitive:&lt;/P&gt;&lt;LI-CODE lang="python"&gt;import arcpy
fgdbList = ["gdb1.gdb", "gdb2.gdb"]
for fgdb in fdbList:
    feature_classes = arcpy.ListFeatureClasses(feature_type='POLYGON', 
                                               workspace = fgdb
                                              )&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 29 Aug 2024 20:09:22 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-ideas/arcpy-list-type-functions-let-us-feed-it-a/idc-p/1529775#M358</guid>
      <dc:creator>AlfredBaldenweck</dc:creator>
      <dc:date>2024-08-29T20:09:22Z</dc:date>
    </item>
    <item>
      <title>Re: arcpy.List[Type] functions: Let us feed it a workspace instead of having to switch the environment</title>
      <link>https://community.esri.com/t5/python-ideas/arcpy-list-type-functions-let-us-feed-it-a/idc-p/1529862#M359</link>
      <description>&lt;P&gt;Following the usual precedence for "old function but good" these would be Data Access functions, say:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;my_workspace = r"C:\path\to\data.gdb"
my_dataset = "ImportantItems"

# Get all feature classes as some sort of proper object, including any dataset objects
all_fcs = [f.name for f in arcpy.da.ListFeatureClasses(my_workspace)]

# Now just the dataset
dataset_fcs = [f.featureType for f in arcpy.da.ListFeatureClasses(f"{my_workspace}\\{my_dataset}")]
alternatively = [f.featureType for f in arcpy.da.ListFeatureClasses(my_workspace, feature_datasets=[my_dataset])]

# Why call many functions when you can call one?
everything = arcpy.da.ListObjects(my_workspace)

# But some database-side filtering is good for large workspaces
special_photos = arcpy.da.ListRasters(my_workspace, "county_*")
special_lines = arcpy.da.ListFeatureClasses(my_workspace, "river_*", "POLYLINE")&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;You get the idea, lots of room for more feature-rich, less stateful functions that play better with all those new typestubs.&lt;/P&gt;</description>
      <pubDate>Thu, 29 Aug 2024 23:10:55 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-ideas/arcpy-list-type-functions-let-us-feed-it-a/idc-p/1529862#M359</guid>
      <dc:creator>DavidSolari</dc:creator>
      <dc:date>2024-08-29T23:10:55Z</dc:date>
    </item>
    <item>
      <title>Re: arcpy.List[Type] functions: Let us feed it a workspace instead of having to switch the environment</title>
      <link>https://community.esri.com/t5/python-ideas/arcpy-list-type-functions-let-us-feed-it-a/idc-p/1534621#M365</link>
      <description>&lt;P&gt;Hey&amp;nbsp;&lt;a href="https://community.esri.com/t5/user/viewprofilepage/user-id/89710"&gt;@ShaunWalbridge&lt;/a&gt;&amp;nbsp;, could we open this back up?&lt;/P&gt;</description>
      <pubDate>Tue, 03 Sep 2024 18:33:34 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-ideas/arcpy-list-type-functions-let-us-feed-it-a/idc-p/1534621#M365</guid>
      <dc:creator>AlfredBaldenweck</dc:creator>
      <dc:date>2024-09-03T18:33:34Z</dc:date>
    </item>
    <item>
      <title>Re: arcpy.List[Type] functions: Let us feed it a workspace instead of having to switch the environment - Status changed to: Open</title>
      <link>https://community.esri.com/t5/python-ideas/arcpy-list-type-functions-let-us-feed-it-a/idc-p/1542218#M368</link>
      <description>&lt;P&gt;Setting status for this idea back to open&lt;/P&gt;</description>
      <pubDate>Tue, 24 Sep 2024 21:52:03 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-ideas/arcpy-list-type-functions-let-us-feed-it-a/idc-p/1542218#M368</guid>
      <dc:creator>HannesZiegler</dc:creator>
      <dc:date>2024-09-24T21:52:03Z</dc:date>
    </item>
    <item>
      <title>Re: arcpy.List[Type] functions: Let us feed it a workspace instead of having to switch the environment</title>
      <link>https://community.esri.com/t5/python-ideas/arcpy-list-type-functions-let-us-feed-it-a/idc-p/1574594#M422</link>
      <description>&lt;P&gt;Another thing I noticed today:&amp;nbsp;&lt;A href="https://pro.arcgis.com/en/pro-app/3.3/arcpy/data-access/listdomains.htm" target="_blank"&gt;ListDomains—ArcGIS Pro | Documentation&lt;/A&gt;&amp;nbsp;takes the workspace as a parameter. This is inconsistent with the current behaviour of the other list functions (although still desired!)&lt;/P&gt;</description>
      <pubDate>Fri, 10 Jan 2025 23:55:58 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-ideas/arcpy-list-type-functions-let-us-feed-it-a/idc-p/1574594#M422</guid>
      <dc:creator>AlfredBaldenweck</dc:creator>
      <dc:date>2025-01-10T23:55:58Z</dc:date>
    </item>
    <item>
      <title>Re: arcpy.List[Type] functions: Let us feed it a workspace instead of having to switch the environment</title>
      <link>https://community.esri.com/t5/python-ideas/arcpy-list-type-functions-let-us-feed-it-a/idc-p/1586350#M435</link>
      <description>&lt;P&gt;Been thinking about this and I think some basic "Manager" classes could make this a lot less tedious:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;&amp;gt;&amp;gt;&amp;gt; workspace = WorkspaceManager(r"C:\path\to\workspace.gdb")
&amp;gt;&amp;gt;&amp;gt; print(workspace.name)
workspace.gdb

&amp;gt;&amp;gt;&amp;gt; print(workspace.feature_classes)
[Path('C:\path\to\workspace.gdb\feature_class1'), Path('C:\path\to\workspace.gdb\feature_class2')]

&amp;gt;&amp;gt;&amp;gt; for fc in workspace.feature_classes.as_strings():
...     print(fc)
C:\path\to\workspace.gdb\feature_class1
C:\path\to\workspace.gdb\feature_class2

&amp;gt;&amp;gt;&amp;gt; arcpy.management.CopyFeatures(workspace.feature_classes.as_strings()[0], str(workspace.path / 'copy_of_feature_class1'))
&amp;gt;&amp;gt;&amp;gt; workspace.feature_classes
[Path('C:\path\to\workspace.gdb\feature_class1'), Path('C:\path\to\workspace.gdb\feature_class2')]

&amp;gt;&amp;gt;&amp;gt; workspace.reload(['feature_classes'])
&amp;gt;&amp;gt;&amp;gt; workspace.feature_classes
[Path('C:\path\to\workspace.gdb\feature_class1'), Path('C:\path\to\workspace.gdb\feature_class2'), Path('C:\path\to\workspace.gdb\copy_of_feature_class1')]&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here's a basic implementation of WorkspaceManager with a bonus name index-able PathList container&lt;/P&gt;&lt;LI-SPOILER&gt;&lt;LI-CODE lang="python"&gt;from __future__ import annotations

from collections import UserList
from typing import overload
from pathlib import Path

from arcpy import (
    EnvManager,
    ListDatasets,
    ListRasters,
    ListTables,
    ListWorkspaces,
    ListFeatureClasses,
    ListFiles,
)

class PathList(UserList[Path]):
    """A list of features that can be accessed by index or name"""
    
    @overload
    def __getitem__(self, index: int) -&amp;gt; Path: ...
    @overload
    def __getitem__(self, name: str) -&amp;gt; Path: ...
    def __getitem__(self, ident: int | str) -&amp;gt; Path:
        if isinstance(ident, int):
            return self.data[ident]
        elif isinstance(ident, str):
            for item in self.data:
                if item.name == ident:
                    return item
            raise KeyError(f"Item {ident} not found")
    
    def as_strings(self) -&amp;gt; list[str]:
        """Returns the list of paths as strings"""
        return [str(item) for item in self.data]
    
class WorkspaceManager:
    # Caches are used to limit the amount of times
    # the List* functions are called, they tend to
    # be slow and if you run them in a loop it will
    # be very slow (like 1-2 seconds per feature_classes)
    __caches__ = (
        '_datasets', 
        '_rasters',
        '_tables', 
        '_workspaces', 
        '_feature_classes', 
        '_files',
    )
    
    __slots__ = ('path', 'name', *__caches__)
    
    def __init__(self, path: Path):
        self.path = Path(path)
        self.name = self.path.name
        
        for cache in self.__caches__:
            setattr(self, cache, None)
    
    def _retrieve(self, func: callable, cache: str):
        if getattr(self, cache):
            return getattr(self, cache)
        
        with EnvManager(workspace=str(self.path)):
            items = func()
        setattr(self, cache, PathList(Path(self.path / item) for item in items))
        
        return getattr(self, cache)
    
    @property
    def datasets(self) -&amp;gt; PathList[Path]:
        return self._retrieve(ListDatasets, '_datasets')
    
    @property
    def rasters(self) -&amp;gt; PathList[Path]:
        return self._retrieve(ListRasters, '_rasters')
    
    @property
    def tables(self) -&amp;gt; PathList[Path]:
        return self._retrieve(ListTables, '_tables')
    
    @property
    def workspaces(self) -&amp;gt; PathList[Path]:
        return self._retrieve(ListWorkspaces, '_workspaces')
    
    @property
    def feature_classes(self) -&amp;gt; PathList[Path]:
        
        # Early return on cache hit
        if self._feature_classes:
            return self._feature_classes

        # retrieve datasets and root feature classes
        self._retrieve(ListDatasets, '_datasets')
        self._retrieve(ListFeatureClasses, '_feature_classes')
        
        # Return root feature classes if no datasets
        if not self.datasets:
            return self._feature_classes
        
        # Extend feature classes with datasets
        for ds in self.datasets:
            with EnvManager(workspace=str(ds)):
                self._feature_classes.extend(self.path / fc for fc in ListFeatureClasses())
        return self._feature_classes
        
    @property
    def files(self) -&amp;gt; PathList[Path]:
        return self._retrieve(ListFiles, '_files')
        
    def reload(self, caches: list[str] = None):
        """Reloads the caches for the workspace
        
        Args:
            caches: A list of caches to reload. If None, all caches are reloaded
        """
        if not caches:
            caches = self.__caches__
        
        for cache in caches:
            if not cache.startswith('_'):
                cache = f"_{cache}"
                
            if cache in self.__caches__:
                setattr(self, cache, None)&lt;/LI-CODE&gt;&lt;/LI-SPOILER&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 18 Feb 2025 15:02:43 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-ideas/arcpy-list-type-functions-let-us-feed-it-a/idc-p/1586350#M435</guid>
      <dc:creator>HaydenWelch</dc:creator>
      <dc:date>2025-02-18T15:02:43Z</dc:date>
    </item>
    <item>
      <title>Re: arcpy.List[Type] functions: Let us feed it a workspace instead of having to switch the environment</title>
      <link>https://community.esri.com/t5/python-ideas/arcpy-list-type-functions-let-us-feed-it-a/idc-p/1589127#M437</link>
      <description>&lt;P&gt;I agree with this idea. To me, the problem is even larger because the whole python API is full of inconsistencies between methods or object property names.&lt;BR /&gt;&lt;BR /&gt;Even the the new cim is awfully conceived.&lt;/P&gt;</description>
      <pubDate>Tue, 25 Feb 2025 20:16:32 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-ideas/arcpy-list-type-functions-let-us-feed-it-a/idc-p/1589127#M437</guid>
      <dc:creator>MaximeDemers</dc:creator>
      <dc:date>2025-02-25T20:16:32Z</dc:date>
    </item>
  </channel>
</rss>

