Quantcast

Can't I define a decorator in a separate file and import it?

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Can't I define a decorator in a separate file and import it?

Saqib Ali


I'm using this decorator to implement singleton class in python:

http://stackoverflow.com/posts/7346105/revisions

The strategy described above works if and only if the Singleton is
declared and defined in the same file. If it is defined in a different
file and I import that file, it doesn't work.

Why can't I import this Singleton decorator from a different file?
What's the best work around?
--
http://mail.python.org/mailman/listinfo/python-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Can't I define a decorator in a separate file and import it?

Ethan Furman-2
Saqib Ali wrote:

>
> I'm using this decorator to implement singleton class in python:
>
> http://stackoverflow.com/posts/7346105/revisions
>
> The strategy described above works if and only if the Singleton is
> declared and defined in the same file. If it is defined in a different
> file and I import that file, it doesn't work.
>
> Why can't I import this Singleton decorator from a different file?
> What's the best work around?

Post the code, and the traceback.

~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Can't I define a decorator in a separate file and import it?

Saqib Ali
In reply to this post by Saqib Ali
BTW Here is the traceback:

>>> import myClass
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "myClass.py", line 6, in <module>
    @Singleton
TypeError: 'module' object is not callable



Here is Singleton.py:



class Singleton:

    def __init__(self, decorated):
        self._decorated = decorated

    def Instance(self):
        try:
            return self._instance
        except AttributeError:
            self._instance = self._decorated()
            return self._instance

    def __call__(self):
        raise TypeError(
            'Singletons must be accessed through the `Instance`
method.')



Here is myClass.py:

#!/usr/bin/env python
import os, sys, string, time, re, subprocess
import Singleton


@Singleton
class myClass:

    def __init__(self):
        print 'Constructing myClass'

    def __del__(self):
        print 'Destructing myClass'
--
http://mail.python.org/mailman/listinfo/python-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Can't I define a decorator in a separate file and import it?

Saqib Ali
In reply to this post by Ethan Furman-2
MYCLASS.PY:

#!/usr/bin/env python
import os, sys, string, time, re, subprocess
import Singleton


@Singleton
class myClass:
    
    def __init__(self):
        print 'Constructing myClass'

    def __del__(self):
        print 'Destructing myClass'


SINGLETON.PY:


#!/usr/bin/env python
import os, sys, string, time, re, subprocess
import Singleton


@Singleton
class myClass:
    
    def __init__(self):
        print 'Constructing myClass'

    def __del__(self):
        print 'Destructing myClass'

TRACEBACK:

>>> import myClass
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "myClass.py", line 6, in <module>
    @Singleton
TypeError: 'module' object is not callable



- Saqib






Post the code, and the traceback.

~Ethan~

--
http://mail.python.org/mailman/listinfo/python-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Can't I define a decorator in a separate file and import it?

Chris Kaynor
On Thu, Dec 22, 2011 at 1:11 PM, Saqib Ali <[hidden email]> wrote:
MYCLASS.PY:

#!/usr/bin/env python
import os, sys, string, time, re, subprocess
import Singleton

This imports the module Singleton, not the class or function.

There are two options to deal with this:
from Singleton import Singleton
imports the name Singleton from the module Singleton, which will be what you are probably expecting. If you wish to keep the namespace, you can also change your call from @Singleton to @Singleton.Singleton
 

@Singleton
class myClass:
    
    def __init__(self):
        print 'Constructing myClass'

    def __del__(self):
        print 'Destructing myClass'


SINGLETON.PY:


#!/usr/bin/env python
import os, sys, string, time, re, subprocess
import Singleton


@Singleton
class myClass:
    
    def __init__(self):
        print 'Constructing myClass'

    def __del__(self):
        print 'Destructing myClass'

TRACEBACK:

>>> import myClass
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "myClass.py", line 6, in <module>
    @Singleton
TypeError: 'module' object is not callable



- Saqib






Post the code, and the traceback.

~Ethan~

--
http://mail.python.org/mailman/listinfo/python-list



--
http://mail.python.org/mailman/listinfo/python-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Can't I define a decorator in a separate file and import it?

Andrew Berg-4
In reply to this post by Saqib Ali
You have the same code for both files...
--
http://mail.python.org/mailman/listinfo/python-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Can't I define a decorator in a separate file and import it?

Marc Christiansen
In reply to this post by Saqib Ali
Saqib Ali <[hidden email]> wrote:
> I'm using this decorator to implement singleton class in python:
>
> http://stackoverflow.com/posts/7346105/revisions
>
> The strategy described above works if and only if the Singleton is
> declared and defined in the same file. If it is defined in a different
> file and I import that file, it doesn't work.
>
> Why can't I import this Singleton decorator from a different file?

Maybe you're doing something wrong. But since you didn't provide any
code, it's impossible to tell what.

> What's the best work around?

As far as I can tell with the information you have given, none is
needed. See below:

0:> python2.7 singleton_test.py # works also with python3.2
Foo created
True
 
#singleton_test.py
from singleton import Singleton
# Singleton is the class from Paul Manta from the SO page
# and singleton.py contains nothing else

@Singleton
class Foo:
    def __init__(self):
        print('Foo created')

f = Foo.Instance()
g = Foo.Instance()

print(f is g)

Grüße
Marc
--
http://mail.python.org/mailman/listinfo/python-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Can't I define a decorator in a separate file and import it?

Ethan Furman-2
In reply to this post by Saqib Ali
Saqib Ali wrote:
> MYCLASS.PY:
>
> #!/usr/bin/env python
> import os, sys, string, time, re, subprocess
> import Singleton

This should be 'from Singleton import Singleton'


> @Singleton
> class myClass:
>    
>     def __init__(self):
>         print 'Constructing myClass'

At this point, the *instance* of myClass has already been constructed
and it is now being initialized.  The __new__ method is where the
instance is actually created.

>
>     def __del__(self):
>         print 'Destructing myClass'
>
>
 > class Singleton:
 >
 >     def __init__(self, decorated):
 >         self._decorated = decorated
 >
 >     def Instance(self):
 >         try:
 >             return self._instance
 >         except AttributeError:
 >             self._instance = self._decorated()
 >             return self._instance
 >
 >     def __call__(self):
 >         raise TypeError(
 >             'Singletons must be accessed through the `Instance`
 > method.')


~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Can't I define a decorator in a separate file and import it?

Saqib Ali
Thanks for pointing out the mistake!
Works.
- Saqib




On Thu, Dec 22, 2011 at 4:31 PM, Ethan Furman <[hidden email]> wrote:
Saqib Ali wrote:
MYCLASS.PY:

#!/usr/bin/env python
import os, sys, string, time, re, subprocess
import Singleton

This should be 'from Singleton import Singleton'



@Singleton
class myClass:
       def __init__(self):
       print 'Constructing myClass'

At this point, the *instance* of myClass has already been constructed and it is now being initialized.  The __new__ method is where the instance is actually created.



   def __del__(self):
       print 'Destructing myClass'


> class Singleton:
>
>     def __init__(self, decorated):
>         self._decorated = decorated
>
>     def Instance(self):
>         try:
>             return self._instance
>         except AttributeError:
>             self._instance = self._decorated()
>             return self._instance
>
>     def __call__(self):
>         raise TypeError(
>             'Singletons must be accessed through the `Instance`
> method.')


~Ethan~


--
http://mail.python.org/mailman/listinfo/python-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Can't I define a decorator in a separate file and import it?

Ben Finney-10
In reply to this post by Saqib Ali
Saqib Ali <[hidden email]> writes:

> BTW Here is the traceback:
>
> >>> import myClass
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>   File "myClass.py", line 6, in <module>
>     @Singleton
> TypeError: 'module' object is not callable

Yes. When you ‘import foo’, you have a module bound to the name ‘foo’. A
module is not callable.

> Here is Singleton.py:

You should name the file ‘singleton.py’ instead; modules should be named
in all lower-case, as PEP 8 recommends.

> Here is myClass.py:

Which should be named ‘my_class.py’, instead, by the same rationale.

Neither of those is necessary, but it will help dispel the confusion
you're experiencing, and help your code be more easily comprehensible to
other Python programmers.

> #!/usr/bin/env python
> import os, sys, string, time, re, subprocess
> import Singleton

So, you should (after the renames suggested) do either::

    import singleton

    @singleton.Singleton
    class my_class:

or::

    from singleton import Singleton

    @Singleton
    class my_class:

Notice how naming the module in lower-case makes it more easily
distinguishable from the class name.

More generally, remember that Python is not Java
<URL:http://dirtsimple.org/2004/12/python-is-not-java.html>, and you
should be grouping your classes into logically coherent files, not
one-file-per-class.

--
 \     “Reality must take precedence over public relations, for nature |
  `\       cannot be fooled.” —Richard P. Feynman, _Rogers' Commission |
_o__)                       Report into the Challenger Crash_, 1986-06 |
Ben Finney
--
http://mail.python.org/mailman/listinfo/python-list
Loading...