Class definition within function

Discussion in 'Python' started by Tomi Lindberg, Aug 2, 2006.

  1. Hi,

    With the following function definition, is it possible to
    create an instance of class C outside the function f (and if
    it is, how)? And yes, I think this is one of those times
    when the real question is why :)

    >>> def f():

    class C(object):
    def __init__(self):
    self.a = 'a'
    return C()

    >>> x = f()
    >>> x.a

    'a'
    >>> y=f.C()


    Traceback (most recent call last):
    File "<pyshell#22>", line 1, in -toplevel-
    y=f.C()
    AttributeError: 'function' object has no attribute 'C'
    >>>


    --
    Tomi Lindberg
     
    Tomi Lindberg, Aug 2, 2006
    #1
    1. Advertising

  2. Tomi Lindberg

    Kay Schluehr Guest

    Tomi Lindberg wrote:
    > Hi,
    >
    > With the following function definition, is it possible to
    > create an instance of class C outside the function f (and if
    > it is, how)?


    def f():
    class C(object):
    def __init__(self):
    self.a = 'a'
    f.C = C
    return C()

    >>> f.C

    <class '__main__.C'>

    > And yes, I think this is one of those times
    > when the real question is why :)


    Definitely ;)
     
    Kay Schluehr, Aug 2, 2006
    #2
    1. Advertising

  3. Tomi Lindberg wrote:

    > Hi,
    >
    > With the following function definition, is it possible to
    > create an instance of class C outside the function f (and if
    > it is, how)? And yes, I think this is one of those times
    > when the real question is why :)
    >
    > >>> def f():

    > class C(object):
    > def __init__(self):
    > self.a = 'a'
    > return C()
    >
    > >>> x = f()
    > >>> x.a

    > 'a'
    > >>> y=f.C()

    >
    > Traceback (most recent call last):
    > File "<pyshell#22>", line 1, in -toplevel-
    > y=f.C()
    > AttributeError: 'function' object has no attribute 'C'


    No, its not. Only inside of it. And the question really is: why? If you need
    a class that can be instantiated regardless of the execution of f, make it
    a globally visible class. If it depends on something f computes, make it a
    function-local one (if you like)

    Diez
     
    Diez B. Roggisch, Aug 2, 2006
    #3
  4. Diez B. Roggisch wrote:

    > No, its not. Only inside of it. And the question really is: why?


    Thanks. And no need to worry, the question was intended as
    fully theoretical.

    --
    Tomi Lindberg
     
    Tomi Lindberg, Aug 2, 2006
    #4
  5. Tomi Lindberg

    Peter Otten Guest

    Tomi Lindberg wrote:

    > With the following function definition, is it possible to
    > create an instance of class C outside the function f (and if
    > it is, how)? And yes, I think this is one of those times
    > when the real question is why :)
    >
    >  >>> def f():
    >         class C(object):
    >                 def __init__(self):
    >                         self.a = 'a'
    >         return C()
    >
    >  >>> x = f()
    >  >>> x.a
    > 'a'


    y = type(x)()

    By the way you get an instance of a different class C every time you call f,
    so that

    isinstance(f(), type(f())

    is False.

    Peter
     
    Peter Otten, Aug 2, 2006
    #5
  6. Tomi Lindberg

    Duncan Booth Guest

    Tomi Lindberg wrote:

    > With the following function definition, is it possible to
    > create an instance of class C outside the function f (and if
    > it is, how)? And yes, I think this is one of those times
    > when the real question is why :)
    >
    > >>> def f():

    > class C(object):
    > def __init__(self):
    > self.a = 'a'
    > return C()
    >
    > >>> x = f()
    > >>> x.a

    > 'a'
    > >>> y=f.C()

    >
    > Traceback (most recent call last):
    > File "<pyshell#22>", line 1, in -toplevel-
    > y=f.C()
    > AttributeError: 'function' object has no attribute 'C'
    > >>>

    >


    Well, you could use 'type(x)()', or object.__subclasses__() will include C
    for as long as the class actually exists. Choosing the correct C from
    object's subclasses could prove somewhat tricky though: remember you'll get
    a new C class every time you call 'f'.
     
    Duncan Booth, Aug 2, 2006
    #6
  7. Peter Otten wrote:

    > By the way you get an instance of a different class C every time you call f,
    > so that
    >
    > isinstance(f(), type(f())
    >
    > is False.


    That I didn't know. Well, that theory won't be seeing much
    practice I guess.

    --
    Tomi Lindberg
     
    Tomi Lindberg, Aug 2, 2006
    #7
  8. Kay Schluehr wrote:

    >
    > Tomi Lindberg wrote:
    >> Hi,
    >>
    >> With the following function definition, is it possible to
    >> create an instance of class C outside the function f (and if
    >> it is, how)?

    >
    > def f():
    > class C(object):
    > def __init__(self):
    > self.a = 'a'
    > f.C = C
    > return C()
    >
    >>>> f.C

    > <class '__main__.C'>


    Not working, unless f has been called at least once. But what I didn't know
    (and always wondered) if the classdefinition inside a function can use the
    outer scope - and apparently, it can! Cool.


    def f(baseclass):
    class C(baseclass):
    def __init__(self):
    self.a = 'a'
    f.C = C
    def foo(self):
    print baseclass
    return C()

    c = f(object)
    print f.C

    c.foo()


    Diez
     
    Diez B. Roggisch, Aug 2, 2006
    #8
  9. Tomi Lindberg

    Kay Schluehr Guest

    Snake is eating itself

    Diez B. Roggisch wrote:
    > Kay Schluehr wrote:
    >
    > >
    > > Tomi Lindberg wrote:
    > >> Hi,
    > >>
    > >> With the following function definition, is it possible to
    > >> create an instance of class C outside the function f (and if
    > >> it is, how)?

    > >
    > > def f():
    > > class C(object):
    > > def __init__(self):
    > > self.a = 'a'
    > > f.C = C
    > > return C()
    > >
    > >>>> f.C

    > > <class '__main__.C'>

    >
    > Not working, unless f has been called at least once.


    Right.

    > But what I didn't know
    > (and always wondered) if the classdefinition inside a function can use the
    > outer scope - and apparently, it can! Cool.


    Yes, the bytecode simply refers to a global name f in the scope of
    __init__. Fortunately the Python compiler is too stupid to guess what f
    might be but simply expects that f exists at runtime. I use this
    "snake is eating itself" pattern very often for passing a module as a
    reference to another module inside of itself:

    --------------------- Module M
    import B

    def eatMe():
    import M
    B.m = M

    if __name__ == '__main__':
    eatMe()

    -----------------------------------

    One might consider M as a component which is definig stuff. Once you
    select such a component it can be used to configure a framework F of
    which B is a part ( B doesn't import M ! ) So F is essentially
    parametrized by M. You ere entering the next level when different
    parametrizations F(M1), F(M2),... can coexist or even refer to each
    other. This isn't just a mental exercise but it's going to be the way
    EasyExtend will support multiple extension languages at the same time
    in the fist beta version of the program. Yes, I know ... everything is
    heavily cyclic and we should do hierarchies instead ;)
     
    Kay Schluehr, Aug 2, 2006
    #9
  10. Tomi Lindberg

    Rick Zantow Guest

    Duncan Booth <> wrote in
    news:Xns9813882C9C0FDduncanbooth@127.0.0.1:

    >> >>> def f():

    >> class C(object):
    >> def __init__(self):
    >> self.a = 'a'
    >> return C()
    >>
    >> >>> x = f()
    >> >>> x.a

    >> 'a'
    >> >>> y=f.C()

    >>

    >


    Of course there's this:

    >>> def f():

    .... class C(object):
    .... def __init__(self):
    .... self.a = 'a'
    .... return C()
    ....
    >>> x = f()
    >>> x.a

    'a'
    >>> y=x.__class__()
    >>> y.a

    'a'
    >>> type(y) == type(x)

    True
     
    Rick Zantow, Aug 2, 2006
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jianli Shen
    Replies:
    1
    Views:
    605
    Victor Bazarov
    Mar 13, 2005
  2. Replies:
    1
    Views:
    2,714
    =?ISO-8859-1?Q?Stefan_N=E4we?=
    Jan 9, 2006
  3. =?ISO-8859-2?Q?Miros=B3aw?= Makowiecki

    Decralation of class inside other class and definition outside this class

    =?ISO-8859-2?Q?Miros=B3aw?= Makowiecki, Jul 13, 2007, in forum: C++
    Replies:
    2
    Views:
    344
    Alf P. Steinbach
    Jul 13, 2007
  4. T.G.
    Replies:
    1
    Views:
    142
    John Wilger
    Nov 4, 2005
  5. jman
    Replies:
    1
    Views:
    97
    David Golightly
    Aug 14, 2007
Loading...

Share This Page