Ir al contenido principal

Ralsina.Me — El sitio web de Roberto Alsina

Python context managers: son fáciles!

Yo es­ta­ba el otro día tra­tan­do de ha­cer co­sas de she­ll scrip­ting con py­thon (co­mo par­te de un se­tu­p.­py mons­truo) y me mo­les­ta­ba que en she­ll es muy fá­cil ha­cer es­to:

cd foo
bar -baz
cd -

O es­to:

pushd foo
bar -baz
popd

O es­to:

(cd foo && bar -baz)

Y en py­thon te­nia que ha­cer es­to, que es lar­go y feo:

cwd = os.getcwd()
try:
    os.chdir('foo')
    os.system('bar -baz')
finally:
    os.chdir(cwd)

Cuan­do en rea­li­dad quie­ro es­to:

with os.chdir('foo'):
    os.system('bar -baz')

Por su­pues­to, eso no es­tá. En­ton­ce­s, pre­gun­té, co­mo se ha­ce eso? Y tu­ve va­rias res­pues­ta­s:

  1. Usá Fa­­bri­­c:

    wi­th   cd("foo"):        run("ba­r")  
  2. No es di­­fí­­ci­­l:

    cla­ss   Dir­Con­textM(ob­ject):        def   __i­ni­t__(se­lf,   new_­dir):            se­lf.new_­dir   =   new_­dir            se­lf.ol­d_­dir   =   No­ne          def   __en­te­r__(se­lf):            se­lf.ol­d_­dir   =   os.ge­tcwd()            os.ch­dir(se­lf.new_­dir)          def   __e­xi­t__(se­lf,   *_):            os.ch­dir(se­lf.ol­d_­dir)  
  3. Es más fá­­ci­­l:

    from   con­tex­tlib   im­port   con­text­ma­na­ger    @con­text­ma­na­ger  def   cd(pa­th):        ol­d_­dir   =   os.ge­tcwd()        os.ch­dir(pa­th)        yield        os.ch­dir(ol­d_­dir)  
  4. Es­­tá bue­­­no, agre­­gué­­mo­s­­lo a pa­­th.­­py pa­­th.­­py

  5. Me­­jor atra­­par ex­­ce­p­­cio­­­nes:

    @con­text­ma­na­ger  def   cd(pa­th):        ol­d_­dir   =   os.ge­tcwd()        os.ch­dir(pa­th)        try:            yield        fi­na­lly:            os.ch­dir(ol­d_­dir)  

Apren­dí co­mo ha­cer con­text ma­na­ger­s, so­bre con­tex­tli­b, so­bre fa­bric y so­bre pa­th.­p­y. Na­da mal pa­ra 15 mi­nu­tos :-)

Χρήστος Γεωργίου / 2012-01-08 11:26:

stackoverflow.com is also useful for such issues:

http://stackoverflow.com/qu...

fungusakafungus / 2012-01-08 13:12:
Vasiliy Faronov / 2012-01-13 13:04:

I’ve been using the shell for, like, six years, and I’ve never heard of `cd -`. This is going to save me some typing over the next six years. Thank you.

Χρήστος Γεωργίου / 2012-01-13 13:17:

`cd -` is equivalent to `cd $OLDPWD` (the variable is managed by the shell), so you are not restricted to moving back to the previous directory; you can also do stuff like: `mv misplaced-file $OLDPWD`

Phil Romero / 2012-12-18 10:15:

I tend to use the dirstack a little differently. Sometimes cd - can take you strange places. But then again, popd'ing a few directories can also lead you astray.


Contents © 2000-2024 Roberto Alsina