user1104854
user1104854

Reputation: 2167

Creating classes and variable assignment

I'm trying to understand how classes work a bit better "under the hood" of python.

If I create a class Foo like so

class Foo:
    bar = True

Foo is then directly accessible, such as print(Foo) or print(Foo.bar)

However, if I dynamically create create a class and don't set it to a variable like so

type('Foo',(),{'bar':True})

If done in the interpreter it shows <class '__main__.Foo'>. However, when I try to print Foo it's undefined...NameError: name 'Foo' is not defined

Does this mean that when a class is created the "traditional" way (the first Foo class above), that python automatically sets a variable for the class of the same name? Sort of like this

# I realize this is not valid, just to convey the idea
Foo = class Foo:
    bar = True

If so, then why doesn't python also create a variable named Foo set to class Foo when using type() to create it?

Upvotes: 3

Views: 162

Answers (4)

Chris Johnson
Chris Johnson

Reputation: 21956

I think you're making this too complicated. If you don't assign a value / object to a symbol, it is always "lost". Doesn't matter if the value / object is a class or something else. Example:

x = 2 + 2

That assigns the value 4 to the symbol x. Compare to:

2 + 2

The operation is carried out but the result 4 isn't assigned to a symbol.

Exact situation you have with classes.

Upvotes: 0

deadcode
deadcode

Reputation: 782

From documentation

class type(name, bases, dict)

With three arguments, return a new type object. This is essentially a dynamic form of the class statement. The name string is the class name and becomes the name attribute; the bases tuple itemizes the base classes and becomes the bases attribute; and the dict dictionary is the namespace containing definitions for class body and becomes the dict attribute. For example, the following two statements create identical type objects:

class X(object):
    a = 1
X = type('X', (object,), dict(a=1))

So yes, I think you have the right idea. type() does create a class but a dynamic form.

Upvotes: 0

James
James

Reputation: 36623

Using type with 3 argument is analogous to using the lambda to create a function. Without assignment the evaluated expression is garbage collected.

However, just you can still create an instance of the class, just like you can immediately call a lambda function.

>>> lambda x: True
<function <lambda> at 0x0000022FF95AB598>
>>> type('Test', (), {'x': True})
<class '__main__.Test'>

You can also create an instance of the class, just like you can immediately call a function

>>> t = type('Test', (), {'x': True})()
>>> t.x
True
>>> type('Test2', (), {'y': 123})().y
123
>>> (lambda x: True)(1000)  # any input returns True
True

Upvotes: 1

marsouf
marsouf

Reputation: 1147

let's compare your problem with function statements and lambdas (because they play the same role here), consider this function f :

def f ():
  return 1

the above snippet of code is not an expression at all, it is a python statement that creates a function named f returning 1 upon calling it.

let's now do the same thing, but in a different way :

f = lambda : 1

the above snippet of code is a python expression (an assignment) that assigns the symbol f to the lambda expression (which is our function) lambda : 1. if we didn't do the assignment, the lambda expression would be lost, it is the same as writing >>> 1 in the python REPL and then trying after that to reference it.

Upvotes: 1

Related Questions