0

I'm getting into Python after forgetting my one intro class many moons ago... I call this code

filedialog.askopenfilename(filetypes = (("TCX files","*.tcx"),("All files","*.*")))  # Works

and it works. I decided to only want *.tcx files so I use

filedialog.askopenfilename(filetypes = (("TCX files","*.tcx")))                      # Doesn't work

and

filedialog.askopenfilename(filetypes = ("TCX files","*.tcx"))                        # Doesn't work

and no dice - I get

"bad file type "*.tcx", should be "typeName {extension ?extensions ...?}"

But then I try

filedialog.askopenfilename(filetypes = [("TCX files","*.tcx")])                      # Works

and it works. I'm okay with Python wanting lists in square brackets, but is there some good reason why the first line worked at all? Does Python treat one-element lists fundamentally different than N>1? Or maybe it's just tkinter's code - the module (filedialog) can handle polymorphic inputs?

rnelsonee
  • 3
  • 4
  • 2
    A one item tuple (not list) is written as (6,) because (6) is just seen as 6 (some expression with or without additional parentheses) by the parser. For brackets there is no ambiguity. – Michael Butscher Nov 21 '19 at 13:59
  • Ah, thank you @MichaelButscher - that would also explain why I see ```(6,)``` for tuples on tutorials when I was trying to figure this out. Interesting choice by the parser. The function (method?) documentation says tuples - is Python just very forgiving for the case of me sending it a list instead? – rnelsonee Nov 21 '19 at 14:04
  • @rnelsonee as I mentioned in my answer both tuples and lists are iterable objects which have the same interface and give the same results when they are accessed (but only to read data and not modify them), so the function works fine with both of them – Marco Zamboni Nov 21 '19 at 14:09
  • 1
    With the exception of the empty tuple `()` (which is not otherwise a valid parenthesized expressinon), it's the *comma* that creates a tuple. Parentheses are only required when the comma could be mistaken for another syntactic construct. Consider `x = 3, 5`, which binds `x` to a tuple containing 3 and 5. Compare `foo(3, 5)` (which calls a function with 2 arguments) with `foo((3, 5))` (which calls a function with a single tuple argument). – chepner Nov 21 '19 at 14:14
  • The `filetypes` argument, I believe, accepts *any* iterable of tuples as a value. The problem with `filedialog.askopenfilename(filetypes = ("TCX files","*.tcx"))` is that the iterable (a tuple) does not contain tuples, but strings. – chepner Nov 21 '19 at 14:18

3 Answers3

2

It seems like the filetypes parameter is expected to be a sequence of tuples. So when you use ("TCX files","*.tcx") as a value for this parameter it is treated as a sequence - which elements are not tuples.

Max Levy
  • 384
  • 4
  • 12
0

A tuple with a single element needs to end in a comma so Python knows you are using a tuple and not parameters. So if you change your second one to this it should work:

filedialog.askopenfilename(filetypes = (("TCX files","*.tcx"),))
paul41
  • 576
  • 7
  • 17
-1

In the first case you got: filetypes = (("TCX files","*.tcx"),("All files","*.*")) which is a tuple of tuples.

In the second you got filetypes = ("TCX files","*.tcx") which is a tuple

The third one you got filetypes = [("TCX files","*.tcx")] which is a list of tuples (only one in this case)

The reason the first one and the third one works is the fact that both of them are iterable objects which contains tuples. The second one doesn't work becouse it is an iterable of strings.

In short words the function expect filetypes to be a collection of tuples, while in the second case it is only the tuple itself

Marco Zamboni
  • 224
  • 1
  • 9