Functions, classes, and instances of a class (objects) are all first class in Python. F() just calls F, which will throw an exception if F is not callable (What is a "callable"?).  The [F] is using F as a key in the dictionary self.frames ([] can be used in other ways as well:
https://docs.python.org/3/reference/expressions.html#index-41) which will throw an exception unless F is hashable and supports an __eq__ method.  Presumably all of StartPage, PageOne, and PageTwo are callable, hashable, and have an __eq__ method.
Perhaps making the code more generic will help to clarify things:
#!/usr/bin/env python3
class frame:
    def __init__(self, *args):
        print(f"frame initialized with {args}")
    def grid(self, **kwargs):
        print(f"frame.grid called with args: {kwargs}")
def StartPage(a=None, b=None):
    return frame(a, b)
class PageOne:
    def __init__(self, *args):
        print(f"PageOne initialized with {args}")
    def grid(self, **kwargs):
        print(f"PageOne.grid called with args: {kwargs}")
class C:
    def __call__(*args):
        return PageOne(args)
PageTwo = C()
container = None
frames = {}
for F in (StartPage, PageOne, PageTwo):
    frame = F(container, None)
    frames[F] = frame
    print( f"F is {F}")
    frame.grid(row=0, column=0, sticky="nsew")
The above code produces the output:
frame initialized with (None, None)
F is <function StartPage at 0x105c63f70>
frame.grid called with args: {'row': 0, 'column': 0, 'sticky': 'nsew'}
PageOne initialized with (None, None)
F is <class '__main__.PageOne'>
PageOne.grid called with args: {'row': 0, 'column': 0, 'sticky': 'nsew'}
PageOne initialized with ((<__main__.C object at 0x105e2a610>, None, None),)
F is <__main__.C object at 0x105e2a610>
PageOne.grid called with args: {'row': 0, 'column': 0, 'sticky': 'nsew'}
In this case, we iterate through the loop three times.  The first time in the loop, the name F is bound to the function StartPage.  Functions are callable; F(container, None) calls the function StartPage with those 2 arguments and binds frame to the object returned by that function call.  That object has a grid method, and frame.grid() calls it.  StartPage is hashable and supports an __eq__ method, so it can be used as a key in the frames dictionary.  The 2nd time through the loop, the name F is cound to the class PageOne, and F(container, None) invokes the class's __init__ method to create an object which is an instance of that class.  Again, that object is hashable and can be used as a key in the frames dictionary, and it contains a grid method.  3rd time through the loop, the name F is bound to the object PageTwo, which was previously initialized as an instance of class C.
In your case, all three objects in the iteration are probably instances of the same class, but I'm hoping the concrete example will help to clarify.