arcpy.ListFeatureClasses doesn't work when using os.path.join

603
5
08-17-2020 02:05 PM
AhmadSALEH1
Occasional Contributor III

Hi,

 I couldn't figure out why arcpy.ListFeatureClasses() doesn't work when I set env.workspace = os.path.join (path,gdb)

and works when I set env.workspace = r"path to the gdb"!

here is an example:

The below script works in my IDE

import arcpy


#Solution 1
gdbANDpath=r"C:\ahmad data\data\MyProject5\f.gdb"


arcpy.env.workspace=gdbANDpath

fclist=arcpy.ListFeatureClasses()
print len(fclist)

prints >> 8

while the following script doesn't work and gives an error:

import arcpy
import os



#Solution 2
gdb_name="f.gdb"
gbd_path="C:\ahmad data\data\MyProject5"


gdbANDpath=os.path.join(gdb_name,gbd_path)
arcpy.env.workspace=gdbANDpath


fclist=arcpy.ListFeatureClasses()
print len(fclist)

Traceback (most recent call last):
File "<module1>", line 31, in <module>
TypeError: object of type 'NoneType' has no len()
>>>

fclist here returns none and fails to create a list of feature classes in the gdb!

PS: Tested on  ArcMap 10.7.1 and 10.6.1, on more than one gdb

5 Replies
DanPatterson
MVP Esteemed Contributor
 import os

gdb_name="f.gdb"
gbd_path="C:\ahmad data\data\MyProject5"

gbd_path
Out[3]: 'C:\x07hmad data\\data\\MyProject5'

Now

gdb_name="f.gdb"
gbd_path= r"C:\ahmad data\data\MyProject5"

gbd_path
Out[5]: 'C:\\ahmad data\\data\\MyProject5'

a little "r" on line 2 goes a long way


... sort of retired...
0 Kudos
AhmadSALEH1
Occasional Contributor III

I am under the assumption that os.path.join(gbd_path,gdb_name) does the same job as using the "r" before the path!

how I can get the same effect of "r" but in a  programmable why? 

gbd_path is coming from a function that returns  the path as the sting 

"C:\ahmad data\data\MyProject5"

in python 3.X I was using

from pathlib import Path

p=Path(os.path.join(gbd_path,gdb_name))

this used to work, but I am not sure what to use in 2.7

0 Kudos
DanPatterson
MVP Esteemed Contributor

you provide this

n = "f.gdb"
g = "C:\ahmad data\data\MyProject5"

os.path.join(g, n)
'C:\x07hmad data\\data\\MyProject5\\f.gdb'  # ---- fails

This works

n = "f.gdb"
g0 = r"C:\ahmad data\data\MyProject5"  # ---- raw format

os.path.join(g0, n)
 'C:\\ahmad data\\data\\MyProject5\\f.gdb'

Or check pathlib in 2.7

Python 2.7.18 documentation 

if you must use arcmap

or

n = "f.gdb"
g ="C:/ahmad data/data/MyProject5"

p = "{}/{}".format(g, n)

p
'C:/ahmad data/data/MyProject5/f.gdb'

which will work fine


... sort of retired...
JoshuaBixby
MVP Esteemed Contributor

Regarding:

I am under the assumption that os.path.join(gbd_path,gdb_name) does the same job as using the "r" before the path!

You are incorrect.  os.path.join won't convert or treat a regular string literal to a raw string literal.

>>> import os
>>>
>>> path = "C:\ahmad data\data\MyProject5"
>>> raw_path = r"C:\ahmad data\data\MyProject5"
>>> name = "f.gdb"
>>>
>>> print(os.path.join(path, name))
C:hmad data\data\MyProject5\f.gdb
>>> 
>>> print(os.path.join(raw_path,name))
C:\ahmad data\data\MyProject5\f.gdb
>>> 

Your issue is that "\a" is a Python escape sequence for ASCII Bell (BEL) character.  If you don't properly escape it, or use raw string notation, that character will make a little chime on your speakers and then be removed from the string.

When you say "this used to work," I am guessing the path was different and didn't involve any Python escape sequences.

AhmadSALEH1
Occasional Contributor III

Thanks Joshua, this explains a lot.  

0 Kudos