Python, the difference between properties with () and without ()

346
4
05-03-2018 05:46 AM
HannesZiegler2
Occasional Contributor II

Hello, I may be missing an important detail about how Python works, and I wanted to see if anyone could help clarify. Short story short  I needed to obtain a string list of domain values for a certain domain of a featureclass I was using, so I put the following code into python window after looking up the necessary classes/functions I needed to obtain said information.

[x for x in arcpy.da.ListDomains(r'Path_To_Geodatabase'if x.name == u'dPubFunctionalClass'][0].codedValues() 

This gave me the following error:

Runtime error

Traceback (most recent call last): File "<string>", line 1, in <module>

TypeError: 'dict' object is not callable

Removing the parenthesis after .codedValues does the trick.

My guess is that .codedValues is not a method of the class Domain, but rather just a variable (a dictionary object) stored within that class. Is this why I get an error message when I attempt to type the .codedValues() instead of just .codedValues?

Thank you!

0 Kudos
4 Replies
DanPatterson_Retired
MVP Esteemed Contributor

some things to examine.  Properties usually don't need (), methods/functions sometimes have a __func__ equivalent.

for example __str__() is a postfix implementation of str().

[0] is just the first in a list/tuple/iterable that meets a condition.  Always get a 'dir' listing to see equivalencies of 'dunder's and methods/properties.

[x for x in [1, 'a', 3, 'b'] if isinstance(x, (int, float))][0]

1

[x for x in [1, 'a', 3, 'b'] if isinstance(x, (int, float))].__str__()

'[1, 3]'

# ==== this fails

[x for x in [1, 'a', 3, 'b'] if isinstance(x, (int, float))].str()
Traceback (most recent call last):

  File "<ipython-input-19-dcabcfd17660>", line 1, in <module>
    [x for x in [1, 'a', 3, 'b'] if isinstance(x, (int, float))].str()

AttributeError: 'list' object has no attribute 'str'

# ----- this works.
str([x for x in [1, 'a', 3, 'b'] if isinstance(x, (int, float))])
'[1, 3]'
JoshuaBixby
MVP Esteemed Contributor

ListDomains—Help | ArcGIS Desktop returns a Domain object; and as you have discovered, codedValues is a property in the Domain class that returns a Python dictionary.

Python allows operator chaining when writing expressions, so it is important to understand 5. Expressions — Python 2.7.15 documentation , especially Operator precedence.  Since codedValues is a property, your code:

[0].codedValues() 

is functionally equivalent to:

codedValues_dict = [0].codedValues
codedValues_dict()

Since Python dictionaries are not callable, your code returns a TypeError.

HannesZiegler2
Occasional Contributor II

Hi Joshua, so I take from this that as I guessed, only functions (or methods) are callable, where any function or method followed by () means it is being called. Usually you call a function with input parameters, but some functions don't require parameters. Variables (or properties) are not callable.

Python Programming/Functions - Wikibooks, open books for an open world 

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

There are several callable types, see "Callable types" under 3. Data model - 3.2 The standard type hierarchy — Python 2.7.15 documentation 

0 Kudos