Solved

Pythoncaller and lists - difference between 2.7 and 3.4?

  • 4 January 2018
  • 6 replies
  • 0 views

Badge +1
def processFeature(feature):
    roleList = feature.getAttribute("tag{}.k")
    print(roleList)
    if roleList!=None:
        for feat in roleList:
            print(feat)

Above is my quite simple python code that successfully prints all key-values for the tag-list of OSM features. This works the same way in 2.7 and 3.4, as expected. However, if I change the attribute to print the member list instead, I get different behaviors between the two.

With the following code:

def processFeature(feature):
    roleList = feature.getAttribute("member{}.ref")
    print(roleList)
    if roleList!=None:
        for feat in roleList:
            print(feat)

It prints nothing in Python 3.4 compat-mode, but does in 2.7 mode.

How come this happens? My initial thought was that since the member-list only contained one member, it would not treat it as a proper list, but even on features with several members, the behavior is the same.

My current workaround is to quite simply use Python 2.7, but this might not always be a good solution.

icon

Best answer by david_r 4 January 2018, 10:48

View original

6 replies

Userlevel 4

What happens if you use the FMELogFile object rather than print statements? E.g.

fmeobjects.FMELogFile().logMessageString(str(roleList))
Badge +1

What happens if you use the FMELogFile object rather than print statements? E.g.

fmeobjects.FMELogFile().logMessageString(str(roleList))
That works just fine! I take it this means that the values are still there internally, I just can't print them as easily. That's good enough for me :)

 

 

Userlevel 4
That works just fine! I take it this means that the values are still there internally, I just can't print them as easily. That's good enough for me :)

 

 

Excellent. I generally try to avoid print statements in the code since they don't necessarily appear in the same order as the features are processed.

 

 

Userlevel 4

I'm wondering if FME opens sys.stdout in buffered mode when running Python 3.x, meaning that print statements are accumulated (buffered) internally until sys.stdout is flushed (and which then echoes to the FME log window).

Try explicitely flushing the print statements, e.g.

print('Hello world!', flush=True)

Alternatively, you can manually flush all buffered print messages in one go like this:

sys.stdout.flush()
Badge +1

I'm wondering if FME opens sys.stdout in buffered mode when running Python 3.x, meaning that print statements are accumulated (buffered) internally until sys.stdout is flushed (and which then echoes to the FME log window).

Try explicitely flushing the print statements, e.g.

print('Hello world!', flush=True)

Alternatively, you can manually flush all buffered print messages in one go like this:

sys.stdout.flush()
Yep, both of these also solve the problem and are perhaps somewhat nicer than the other one. I'll accept this one. Thanks, David.

 

 

Userlevel 4
Yep, both of these also solve the problem and are perhaps somewhat nicer than the other one. I'll accept this one. Thanks, David.

 

 

Good to hear. Just be aware of one important distinction: print only echoes to the log window and not to the log file. Using FMELogFile echoes the messages to both the log window and the log file.

Reply