1

In Python 3.x official documents, we could find the source code about functools.partial, below:

def partial(func, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = keywords.copy()
        newkeywords.update(fkeywords)
        return func(*args, *fargs, **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc

However, I can't understand the syntax for below

newfunc.func = func
newfunc.args = args
newfunc.keywords = keywords

Where could see about these similar syntax? I am pretty puzzled. Because, I got a fatal error when I try the below code:

def func(A, B):
    def func_m(*fargs, **fkargs):
        print(D+C)
        print(fargs, fkargs)
    func_m.D = A
    func_m.C = B
    return func_m

f = func(1, 2)
f()

But i got a NameError that name 'D' is not defined after i call f().

Save my time, please! Thanks.

2
  • Not enitrely sure, but what is the purpose of D and C? Couldn't you use A and B directly inside func_m ? Commented Nov 24, 2019 at 8:18
  • The problem is not in the = lines, that’s just an assignment like any other. Notice how you’re introducing previously undefined variables D and C, while all of partials names are previously defined. Commented Nov 24, 2019 at 8:28

2 Answers 2

2

The reason partial's code doesn't cause a NameError and yours does is:

The args and keywords that are used inside the def newfunc block are not the attributes set on newfunc outside that block, but rather the parameters of the same name that are passed to partial itself.

The attributes that are set on newfunc can be accessed by the caller to partial to see which args/kwargs are already set on that function, but if you remove them from partial's logic it will still work just the same (try it :) )

Sign up to request clarification or add additional context in comments.

3 Comments

awesome! i try it then it work very well, so that mean is i can not assign a variance like D+C outside that block via function_name.xxxx? my problem is it.
and i just want to understand, which situation i could correctly use these syntax, like function_name.xxxx, then still work perfectly.
i try to rename newfunc.args = args to newfunc.var1 = args then i will get same error namely 'NameError', so the args and keywords are both default keyword for functions attributes like __name__ or __code__?
0

Those lines are for storing attributes which are sometimes handy for inspection. They do not affect what happens when the body of newfunc runs. In your case you can just do this:

def func(A, B):
    def func_m(*fargs, **fkargs):
        print(A+B)
        print(fargs, fkargs)
    return func_m

f = func(1, 2)
f()

3 Comments

what do you mean by they are sometimes handy for inspection?
yup, i know your code could work, but my problem is that i can't understand why the partial function could use the way like functions.xxx = xxx to assign value.
@ihades You’re just assigning an arbitrary value to an arbitrary attribute on an arbitrary object. It has absolutely no deeper meaning and has no direct functionality within that code snippet.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.