Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Currying using python with-statement?

I am not sure if this is 'good python practice', but would it be possible to, say, define a custom File-object that could do something like:

myfile = myopen('myfile.txt')
with myfile:
    write('Hello World!') #notice we don't put "myfile.write(..)" here!

i.e the File-context creates a function "write()" so that we don't have to type myfile.write(..) etc. It saves typing and makes the purpose clearer in some cases. For instance:

myboard = ChessBoard()
with ChessBoard():
    make_move("e4")
    make_move("e5")
    give_up()

as opposed to

myboard = ChessBoard()
with ChessBoard():
    make_move("e4",board=myboard)
    make_move("e5",board=myboard)
    give_up(board=myboard)

The question is: should I do this? and HOW can I do it? I am guessing I would have to modify the globals()-dict somehow, but that seems like a bad idea..

EDIT: Ok thanks! I got multiple good answers advising me not to do this. So I won't do it :o)

like image 629
epeld Avatar asked May 21 '26 20:05

epeld


2 Answers

This is not what context managers are for and, as has been remarked, I beats the "explicit is better than implicit" principle. The only way to make it work would have to work around Python's compositional semantics, which are one of its strong points. What you can do to save typing, if there's only a single method to be called multiple times, is:

move = ChessBoard().make_move
move("e4")
move("e5")

Or with multiple such methods:

board = ChessBoard()
move = board.make_move
give_up = board.give_up
# call methods

(In FP terms, this is actually partial application, not currying.)

like image 128
Fred Foo Avatar answered May 23 '26 09:05

Fred Foo


First off, this is not a good idea at all. Explicit is better than implicit -- by explicitly mentioning the board, the reader (which may be you in a few weeks!) can instantly tell which board is being operated on. Also, there is no need. You can have more convenient syntax in other ways: For example, make the functions methods of the individual objects. And drop the pointless context manager (what's it supposed to do? You already create an object beforehand!).

To do this, you'd need global state, but not globals specifically. Say, a global (module-level to be exact) stack of objects, the context manager pushes and pops the object, and the individual functions look at the top of that stack. It actually wouldn't be too hard to implement if you know your stuff, but as I said before, there is no reason to.


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!