# Clip each layer in mxd with Arcpy

In the arcpy window in arcgis, I'm trying to:

• iterate through each layer in an mxd

• clip the layer to a shapefile (also in the mxd)

• export each clipped layer to a geodatabase, with the name of each new clipped feature class being the same as the input layer.

My code:

mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd, '')[0]
import os
workSpace = r"J:\foo\bar\test.gdb"
for lyr in arcpy.mapping.ListLayers(mxd, '', df):
fullPath = os.path.join(workSpace, lyr)
arcpy.Clip_analysis(lyr, "clipping_shape", fullPath)


Error message:

TypeError: object of type 'Layer' has no len()


Edited to add: above error message appears even without the clip_analysis portion of the code, so presumably something is off with the fullPath variable.

I've read this answer but I don't know how to use this portion of the code when populating a geodatabase instead of using shapefiles.

"{}.shp".format(lyr)

• "{}.shp".format(lyr) just helps name the shapefile. In this case you shouldn't need it as you're saving to a geodatabase not a shapefile. Is that the entire error message? – Midavalo Apr 27 '16 at 4:27
• Thanks @Midavalo whole message is: Runtime error Traceback (most recent call last): File "<string>", line 2, in <module> File "C:\Python27\ArcGIS10.3\Lib\ntpath.py", line 66, in join p_drive, p_path = splitdrive(p) File "C:\Python27\ArcGIS10.3\Lib\ntpath.py", line 114, in splitdrive if len(p) > 1: TypeError: object of type 'Layer' has no len() – Rosie Bell Apr 27 '16 at 4:32
• @Midavalo I've added more information to the question under the error message. – Rosie Bell Apr 27 '16 at 4:34

The line os.path.join is throwing the error. This can be fixed by changing that line to

fullPath = os.path.join(workSpace, lyr.name)


although personally I'd remove it and use the following:

mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd, '')[0]
workSpace = r"J:\foo\bar\test.gdb"
for lyr in arcpy.mapping.ListLayers(mxd, '', df):
fullPath = r"{}\\{}".format(workSpace, lyr)
if lyr.name <> "clipping_shape":
arcpy.Clip_analysis(lyr, "clipping_shape", fullPath)


In the line fullPath = r"{}\\{}".format(workSpace, lyr) the {} are placeholders for text that are input from the .format(workSpace, lyr) where workSpace goes into the first {} and lyr into the second to construct the full path. So if your layer name (lyr) was "testlayer" you'd end up with fullPath = r"J:\foo\bar\test.gdb\testlayer"

I also added the line if lyr.name <> "clipping_shape" otherwise you'll be clipping your clipping_shape as well. You can remove this line if you still want it to do that.

• why replace os.path.join with a format string? why not just replace lyr with lyr.name in fullPath? – Nxaunxau Apr 27 '16 at 4:47
• for me it's personal preference and not needing to import os. – Midavalo Apr 27 '16 at 4:48
• but yes that would do it too – Midavalo Apr 27 '16 at 4:55