Class definition within function

T

Tomi Lindberg

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 :)
class C(object):
def __init__(self):
self.a = 'a'
return C()

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

Kay Schluehr

Tomi said:
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()
And yes, I think this is one of those times
when the real question is why :)

Definitely ;)
 
D

Diez B. Roggisch

Tomi said:
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 :)

class C(object):
def __init__(self):
self.a = 'a'
return 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
 
T

Tomi Lindberg

Diez said:
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.
 
P

Peter Otten

Tomi said:
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
 
D

Duncan Booth

Tomi said:
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 :)

class C(object):
def __init__(self):
self.a = 'a'
return 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'.
 
T

Tomi Lindberg

Peter said:
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.
 
D

Diez B. Roggisch

Kay said:
def f():
class C(object):
def __init__(self):
self.a = 'a'
f.C = C
return 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
 
K

Kay Schluehr

Diez said:
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 ;)
 
R

Rick Zantow

Of course there's this:
.... class C(object):
.... def __init__(self):
.... self.a = 'a'
.... return C()
....True
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top