简体   繁体   中英

Why is this Python syntax error Not an error?

I came across the following error today -- This is a minimal example.

class Foo:

    def __init__( self, filename ):
    #    set-up LOG_FILE

    def log( self, msg ):
        print( msg, file=self.LOG_FILE )

#------

##  A) Problem here:
#
foo = Foo
(
    "/dev/stderr"
)

#------

def  bar( log_line ):
    foo.log( "bar:  "+ log_line )

##  elsewhere ...

bar("this is a test")   #  B) example line

You no doubt realise that the statement A needs to be corrected, viz .:

##  C) Corrected syntax:   
#
foo = Foo            \  
(                    \
    "/dev/stderr"    \   
)      

That is a simple fix-up. However, when you run the first version (with the problem) the output is most misleading. To begin with, Python runtime executes the statement at (B).

Traceback (most recent call last):
   :
   foo.log( "bar:  "+ log_line )
TypeError: log() missing 1 required positional argument: 'log_line'

After not catching the original error, the traceback looks for some kind of "valid syntax" reason for the problem. The runtime error will be misleading because the interpreter thinks the code was OK.

I checked with pylint as well. It has an interesting understanding of the error as well:

E1120: No value for argument 'self' in unbound method call (no-value-for-parameter)

Which confused everyone. It was only after putting the constructor on one-line that we saw the problem clearly.

Thus the question is:

  • Given that the backslashes are Required
  • Why is that syntax Not a Syntax Error?

Should this be reported as a bug? For this exercise, I was using Python v3.7.5 and pylint

pylint 2.2.2
astroid 2.1.0
Python 3.7.5 (default, Nov 20 2019, 09:21:52) 
[GCC 9.2.1 20191008]

This is simply two statements:

foo = Foo

Defines a new variable called foo, which refers to the class Foo . Thereafter you can do things like

foo("/dev/stderr")

and that will create a new instance of Foo.

The second statement is

(
    "/dev/stderr"
)

which is just a parenthetical expression that contains a string; it does nothing (akin to writing just (1) on a line by itself).

In general, Python style guides recommend that you always keep the opening paren of a function call or constructor on the same line as the class itself (preferably without any space, eg Foo( ). If you do that, you don't even need backslashes, because the statement will continue until the closing paren. Backslashes for line continuation are heavily discouraged in real Python code; there's almost always a better/cleaner way to write the code that doesn't need the backslashes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM