-1

Following is a model given by a module.

If you look inside of it, you can check two definitin of functions are defined in a nested depth.

I've never seen this before.

How's it working?

def load(filepath, shape_only=False):
  def readpca(f, nv):
    nc,nd  = struct.unpack('<II', f.read(8))
    assert(nd == 3*nv)
    funcs  = [[struct.unpack('<d', f.read(8))[0] for d in range(nd)]
              for c in range(nc)]
    (nm,)  = struct.unpack('<I', f.read(4))
    assert(nm == 3*nv)
    # fyi: elements are ordered x1,y1,z1,x2,y2,z2,...xnv,ynv,znv.
    vmean  = [struct.unpack('<d', f.read(8))[0] for i in range(nm)]
    (ne,)  = struct.unpack('<I', f.read(4))
    values = [struct.unpack('<d', f.read(8))[0] for i in range(ne)]
    return PCAModel(vmean, funcs, values)

  with open(filepath, 'rb') as f:
    nv,nt = struct.unpack('<II', f.read(8))
    # fyi: faces is a list of tuples (each tuple contains 3 vertex indices).
    faces = [struct.unpack('<III', f.read(12)) for i in range(nt)]
    shape = readpca(f, nv)
    try:
      textr = None if shape_only else readpca(f, nv)
    except Exception:
      print('No texture data. Returning shape-only model.')
      textr = None

  return MorphModel(faces, shape, textr)
Beverlie
  • 461
  • 1
  • 6
  • 19
  • Possible duplicate of [Nested Function in Python](https://stackoverflow.com/questions/1589058/nested-function-in-python) – Matthew Story Jul 05 '18 at 05:12

1 Answers1

0

The function definition in Python:

def foo():
    pass

and a variable assignment:

foo = 17

are completely identical, except one binds to a variable (foo) a function value, and the other, a non-function value (and the fact that Python chose to make them wildly dissimilar, syntactically).

So let's see, what would be the difference between the following two?

foo = 17
def bar():
    print(foo)

def bar():
    foo = 17
    print(foo)

In the first one, the scope of the variable foo is wider than the function bar; in the second one, foo is local to bar.

Almost exactly the same thing in your case. The load function needs a helper function readpca, but it is not interested in having it available outside load, so it defines it as local to the function.

Actually, with functions it is a bit more complex because of the concept of closure: the tl;dr is that a function will have access to variables of the environment it is defined in. It is not used here at all, but readpca would have access to the variables filepath and readonly, if it wanted to; if readpca was defined outside load, those would have to be passed via extra parameters, if readpca were interested in them. This closure effect is another reason a function might want to be defined inside another function.

Amadan
  • 191,408
  • 23
  • 240
  • 301