Hello!
I have been running in to some problems when using
contextlib.nested(). My problem arises when using code similar to
this:
from __future__ import with_statement
from contextlib import nested
class Foo(object):
def __init__(self, tag, fail=False):
print 'ctor', tag
self.tag = tag
if fail:
raise Exception()
def __enter__(self):
print '__enter__', self.tag
return self
def __exit__(self, *args):
print '__exit__', self.tag
with nested(Foo('a'), Foo('b', True)) as (a, b):
print a.tag
print b.tag
Here the construction of b fails which in turn means that the
contextmanager fails to be created leaving me a constructed object (a)
that needs to be deconstructed in some way. I realize that nested() is
in a tight spot here to do anything about it since it doesn't exist.
This behavior makes it hard for me to use the with statement (using
nested()) the way I want.
Has anyone else been running in to this? Any tips on how to handle
multiple resources?
Regards,
Mattias 7 1961
brasse wrote:
Hello!
I have been running in to some problems when using
contextlib.nested(). My problem arises when using code similar to
this:
from __future__ import with_statement
from contextlib import nested
class Foo(object):
def __init__(self, tag, fail=False):
print 'ctor', tag
self.tag = tag
if fail:
raise Exception()
def __enter__(self):
print '__enter__', self.tag
return self
def __exit__(self, *args):
print '__exit__', self.tag
with nested(Foo('a'), Foo('b', True)) as (a, b):
print a.tag
print b.tag
Here the construction of b fails which in turn means that the
contextmanager fails to be created leaving me a constructed object (a)
that needs to be deconstructed in some way. I realize that nested() is
in a tight spot here to do anything about it since it doesn't exist.
This behavior makes it hard for me to use the with statement (using
nested()) the way I want.
Has anyone else been running in to this? Any tips on how to handle
multiple resources?
I don't fully understand this. Why is in need to be deconstructed? Sure, the
object is created, but whatever is actually done on initialization which is
non-trivial should of course to the __enter__-method - which isn't called.
So, a falls out of a scope & gets GC'ed. What else do you expect to happen?
Diez
On Thu, 06 Nov 2008 01:02:34 -0800, brasse wrote:
Hello!
I have been running in to some problems when using contextlib.nested().
My problem arises when using code similar to this:
from __future__ import with_statement
from contextlib import nested
class Foo(object):
def __init__(self, tag, fail=False):
print 'ctor', tag
self.tag = tag
if fail:
raise Exception()
def __enter__(self):
print '__enter__', self.tag
return self
def __exit__(self, *args):
print '__exit__', self.tag
with nested(Foo('a'), Foo('b', True)) as (a, b):
print a.tag
print b.tag
Here the construction of b fails which in turn means that the
contextmanager fails to be created leaving me a constructed object (a)
that needs to be deconstructed in some way. I realize that nested() is
in a tight spot here to do anything about it since it doesn't exist.
This behavior makes it hard for me to use the with statement (using
nested()) the way I want.
Has anyone else been running in to this? Any tips on how to handle
multiple resources?
Your problem does not seem to be connected to context managers. The error
occurs before calling `contextlib.nested` at all::
>>foo = [Foo('a')]
ctor a
>>with nested(*foo) as a: print a
...
__enter__ a
[<__main__.Foo object at 0x7fbc29408b90>]
__exit__ a
>>foo = [Foo('a'), Foo('b', True)]
ctor a
ctor b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 7, in __init__
raise Exception()
Exception
If you need to deconstruct object `a` from your example, your staging is
probably broken. Allocate the resource in `__init__` but only go live
just in `__enter__`. If you do not enter the context, then, you won't
need to deconstruct it as well.
HTH,
--
Robert "Stargaming" Lehmann
On Nov 6, 11:43*am, Robert Lehmann <stargam...@gmail.comwrote:
On Thu, 06 Nov 2008 01:02:34 -0800, brasse wrote:
Hello!
I have been running in to some problems when using contextlib.nested().
My problem arises when using code similar to this:
from __future__ import with_statement
from contextlib import nested
class Foo(object):
* * def __init__(self, tag, fail=False):
* * * * print 'ctor', tag
* * * * self.tag = tag
* * * * if fail:
* * * * * * raise Exception()
* * def __enter__(self):
* * * * print '__enter__', self.tag
* * * * return self
* * def __exit__(self, *args):
* * * * print '__exit__', self.tag
with nested(Foo('a'), Foo('b', True)) as (a, b):
* * print a.tag
* * print b.tag
Here the construction of b fails which in turn means that the
contextmanager fails to be created leaving me a constructed object (a)
that needs to be deconstructed in some way. I realize that nested() is
in a tight spot here to do anything about it since it doesn't exist.
This behavior makes it hard for me to use the with statement (using
nested()) the way I want.
Has anyone else been running in to this? Any tips on how to handle
multiple resources?
Your problem does not seem to be connected to context managers. The error
occurs before calling `contextlib.nested` at all::
* *>>foo = [Foo('a')]
* *ctor a
* *>>with nested(*foo) as a: print a
* *...
* *__enter__ a
* *[<__main__.Foo object at 0x7fbc29408b90>]
* *__exit__ a
* *>>foo = [Foo('a'), Foo('b', True)]
* *ctor a
* *ctor b
* *Traceback (most recent call last):
* * *File "<stdin>", line 1, in <module>
* * *File "<stdin>", line 7, in __init__
* * * *raise Exception()
* *Exception
If you need to deconstruct object `a` from your example, your staging is
probably broken. Allocate the resource in `__init__` but only go live
just in `__enter__`. If you do not enter the context, then, you won't
need to deconstruct it as well.
HTH,
--
Robert "Stargaming" Lehmann
Diez, Robert,
OK. The practice of "going live" or doing non-trivial initialization
in __enter__ is new to me. I'm new to Python with a C++ background, so
that shouldn't be a surprise. :-)
Ideally I would like to put all initialization in __init__ since then
I would be able to use my object right after constructing it, without
having to use it in a with statement. The reason I'm struggling with
this is probably my C++ background. I'm rally accustomed to design
with RAII in mind. Acquiring all resources in the ctor and releasing
all resources in the dtor is *really* handy.
If you had a class that wanted to acquire some external resources that
must be released at some point, how would you rewrite the code from my
example?
:.:: mattias
Diez, Robert,
>
OK. The practice of "going live" or doing non-trivial initialization
in __enter__ is new to me. I'm new to Python with a C++ background, so
that shouldn't be a surprise. :-)
Ideally I would like to put all initialization in __init__ since then
I would be able to use my object right after constructing it, without
having to use it in a with statement. The reason I'm struggling with
this is probably my C++ background. I'm rally accustomed to design
with RAII in mind. Acquiring all resources in the ctor and releasing
all resources in the dtor is *really* handy.
Yes, but this is a C++ idiom that does not translate well to python's
GC-based approach. Which is the *exact* reason why contexts have been
created in the first place.
If you had a class that wanted to acquire some external resources that
must be released at some point, how would you rewrite the code from my
example?
If you *can*, use a context. Use __enter__ and __exit__. Try really hard to
use it that way.
If not - create a specific finalize-method or some such, and try not to
forget to call that. Potentially with an atexit-handler or some such.
the problem is that python can't guarantee that a __del__-method is invoked
at all, and *if* it is, it might find other stuff being released already
that it relies upon - e.g. imported modules being freed & not known
anymore.
Diez
On Nov 6, 5:45*pm, "Diez B. Roggisch" <de...@nospam.web.dewrote:
If you had a class that wanted to acquire some external resources that
must be released at some point, how would you rewrite the code from my
example?
If you *can*, use a context. Use __enter__ and __exit__. Try really hard to
use it that way.
My case becomes something like this:
from __future__ import with_statement
from contextlib import nested
class Foo(object):
def __init__(self, tag, fail=False):
print 'ctor', tag
self.tag = tag
self.fail = fail
def __enter__(self):
if self.fail:
print 'fail', self.tag
raise Exception()
print '__enter__ acquire resource', self.tag
return self
def __exit__(self, *args):
print '__exit__ release resource', self.tag
with nested(Foo('a'), Foo('b', True)) as (a, b):
print a.tag
print b.tag
When using Foo objects in a with statement this works good for me. But
what if I want to use Foo objects as members in a class for example?
Since we now must contruct an instance of Foo in two stages the code
becomes less than ideal.
def __init__(self):
self.x = Foo()
self.x.__enter__()
Perhaps there is no way to write classes that fits neatly into all (or
even these two) usage scenarios?
If not - create a specific finalize-method or some such, and try not to
forget to call that. Potentially with an atexit-handler or some such.
It seems to me that I have to use the with statement (or some try-
finally construct) to be able to release all resources when my code
throws exceptions(). Just remembering to call close/finalize/destroy
will not be enough.
:.:: mattias
brasse wrote:
with nested(Foo('a'), Foo('b', True)) as (a, b):
Â* Â* print a.tag
Â* Â* print b.tag
If been watching this thread for a while, and I think that your problems
will go away if you write actual nested with-blocks:
with Foo("a") as a:
with Foo("b") as b:
print a.tag
print b.tag
Why look for a complex solution if there is a simple one?
Peter
On Nov 7, 10:33*am, Peter Otten <__pete...@web.dewrote:
brasse wrote:
with nested(Foo('a'), Foo('b', True)) as (a, b):
* * print a.tag
* * print b.tag
If been watching this thread for a while, and I think that your problems
will go away if you write actual nested with-blocks:
with Foo("a") as a:
* * with Foo("b") as b:
* * * * print a.tag
* * * * print b.tag
Why look for a complex solution if there is a simple one?
That works great if you are only working with two objects. It gets a
bit uglier when you need to use three or more objects. I'm just trying
to figure out if there is some kind of best practice in the Python
community that works well (even with more than two objects) for the
two usage scenarios I have described.
:.:: mattias This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Andy Baker |
last post by:
Hi there,
I'm learning Python at the moment and trying to grok the thinking behind
it's scoping and nesting rules.
I was googling for nested functions and found this Guido quote:...
|
by: Erik Bongers |
last post by:
Hi,
Nested classes only seem to be able to access static members of the
surrounding class :
class SurroundingClass
{
public:
class InnerClass
{
public:
|
by: B0nj |
last post by:
I've got a class in which I want to implement a property
that operates like an indexer, for the various colors
associated with the class.
For instance, I want to be able to do 'set' operations...
|
by: Robert W. |
last post by:
I've almost completed building a Model-View-Controller but have run into a
snag. When an event is fired on a form control I want to automatically
updated the "connnected" property in the Model. ...
|
by: Tomas Sieger |
last post by:
Hi all,
I'm in doubt with the following code:
class Base {
public:
class Nested {};
};
class Derived:public Base {
public:
class Nested {
|
by: Peter Olcott |
last post by:
http://www.tommti-systems.de/go.html?http://www.tommti-systems.de/main-Dateien/reviews/languages/benchmarks.html
The above link shows that C# is 450% slower on something as simple as a nested
loop....
|
by: Paul Rubin |
last post by:
it looks like contextlib.closing fails to be idempotent,
i.e. wrapping closing() around another closing() doesn't work.
This is annoying because the idea of closing() is to let you
use legacy...
|
by: jdurancomas |
last post by:
Dear all,
I'm trying to declare the operator++ to a nested class. The nested
class is not template but the container it is.
The code used in teh sample program is included bellow:
...
|
by: Neal Becker |
last post by:
http://www.python.org/doc/2.5.2/lib/module-contextlib.html has this example:
from contextlib import contextmanager
@contextmanager
def tag(name):
print "<%s>" % name
yield
print "</%s>" %...
|
by: taylorcarr |
last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
|
by: aa123db |
last post by:
Variable and constants
Use var or let for variables and const fror constants.
Var foo ='bar';
Let foo ='bar';const baz ='bar';
Functions
function $name$ ($parameters$) {
}
...
|
by: ryjfgjl |
last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
|
by: emmanuelkatto |
last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud.
Please let me know.
Thanks!
Emmanuel
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
| |