1

For example:

class Foo:
    def __init__(self):
        self.bar = "baz"

    def test(self):
        return "secret value that can only accessed in this function!!"

How can I do this:

x = Foo()

with x.test() as f:
    print(f)
    # "secret value that can only be accessed in this function!!"

Without raising an error?

docyoda
  • 121
  • 8
  • `with` is used for contextmanagers, not all methods will return a context manager, have a look at https://stackoverflow.com/questions/3012488/what-is-the-python-with-statement-designed-for – luigibertaco Dec 02 '19 at 23:37
  • 2
    This is an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). What are you trying to accomplish? – Selcuk Dec 02 '19 at 23:40
  • Why is `Foo.test` an instance method if it doesn't use the instance? And if `Foo` doesn't really do anything, why not make `test` a plain function? Why do you need to use a `with` statement instead of just calling the method? – wjandrea Dec 02 '19 at 23:45
  • I agree with @Selcuk. This is another good resource on the subject: http://xyproblem.info/. – AMC Dec 02 '19 at 23:57

2 Answers2

2

You can use contextlib.contextmanager:

import contextlib

class Foo:
   @contextlib.contextmanager
   def bar(self):
       yield 'secret'

and use it like so:

>>> x = Foo()

>>> with x.bar() as f:
...     print(f)
secret

Note however that this is not sufficient to "hide" a variable from outside manipulation (so your secret will never be truly secret). Python is dynamic to the core, so most "security measures" rely on an unwritten convention that users do not try and actively circumvent them.

Dion
  • 1,492
  • 11
  • 14
2

You should need a reason for using contextmanagers, but only as an example you could do something like this:

from contextlib import contextmanager

class Foo:
    def __init__(self):
        self.bar = "baz"

    @contextmanager
    def test(self):
        print("doing something before entering `with block`")
        yield "secret value that can only accessed in this function!!"
        print("doing something else after exiting `with block`")

The usage will return:

x = Foo()

with x.test() as f:
    print(f)

# "doing something before entering `with block`"
# "secret value that can only be accessed in this function!!"
# "doing something else after exiting `with block`"

More information at:

https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager

What is the python "with" statement designed for?

luigibertaco
  • 1,112
  • 5
  • 21