Python Forum
How does this code create a class? - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: How does this code create a class? (/thread-41990.html)



How does this code create a class? - Pedroski55 - Apr-19-2024

I don't understand classes in Python!

Why do I get a class like this, without declaring a class??

Employee = type("Employee", (object,), dict())
Enter Employee in Idle:

Employee

Output:
<class '__main__.Employee'>
Make an instance of Employee:

employee = Employee()

# Set salary to 1000
setattr(employee,"salary", 1000 )

# Get the Salary
value = getattr(employee, "salary")
print(value) # returns 1000
employee.salary # returns 1000



RE: How does this code create a class? - buran - Apr-19-2024

Did you check the docs:
https://docs.python.org/3/library/functions.html#type

Quote: class type(object)
class type(name, bases, dict, **kwds)

With one argument, return the type of an object. The return value is a type object and generally the same object as returned by object.__class__.

The isinstance() built-in function is recommended for testing the type of an object, because it takes subclasses into account.

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 contains the base classes and becomes the __bases__ attribute; if empty, object, the ultimate base of all classes, is added. The dict dictionary contains attribute and method definitions for the class body; it may be copied or wrapped before becoming the __dict__ attribute. The following two statements create identical type objects:

class X:
    a = 1

X = type('X', (), dict(a=1))



RE: How does this code create a class? - Gribouillis - Apr-19-2024

(Apr-19-2024, 10:56 AM)Pedroski55 Wrote: I don't understand classes in Python!

Why do I get a class like this, without declaring a class??
Every object in python is an instance of some class. This applies to classes. Normally, classes are instances of the type type
>>> class A:
...     pass
... 
>>> type(A)
<class 'type'>
Well is type an instance of something else?
>>> type(type)
<class 'type'>
>>> isinstance(type, type)
True
>>> 
type is an instance of itself.

Can classes be instances of something else than type?

YES! this is called a metaclass.
>>> class MetaSpam(type):
...     pass
... 
>>> class Spam(metaclass=MetaSpam):
...     pass
... 
>>> 
>>> type(Spam)
<class '__main__.MetaSpam'>
The class Spam is an instance of MetaSpam, a derived type of type.


RE: How does this code create a class? - Pedroski55 - Apr-19-2024

Thanks for the replies.

I have no theoretical knowledge of computing. I am mainly interested in what practical use anything can be, in order to make a given task easier and faster.

Not sure how querying the type of type, or knowing that a class is an instance of type helps. Why do we need class in that case?

I thought type was only for querying what kind of variable you had, now, using type I can create a class and go on create instances of that class (=type)!

Quote:Now what can we do with instance objects? The only operations understood by instance objects are attribute references. There are two kinds of valid attribute names: data attributes and methods.



RE: How does this code create a class? - Gribouillis - Apr-20-2024

(Apr-19-2024, 04:38 PM)Pedroski55 Wrote: I am mainly interested in what practical use anything can be, in order to make a given task easier and faster.
Having a consistent language makes the task of programming that language easier and faster. That's why it is good design that classes in Python are first class objects like any other object. For example it allows programmers to pass classes as arguments to function or to make collections of classes etc. Not all languages allow that.

Perhaps you don't use these features directly in your code because you're not interested in metaprogramming and other advanced features that Python allows. If you ever use introspection or serialization or packaging etc, you'll be using these advanced features through libraries that are built on them.
(Apr-19-2024, 04:38 PM)Pedroski55 Wrote: I thought type was only for querying what kind of variable you had, now, using type I can create a class and go on create instances of that class (=type)!
When you have a class A, you can use A() as a function to create instances of A objects. In the same way you can use type() to create instances of type object, that is to say classes.

Class definitions are a syntactic facility to ease the creation of most classes. The situation is similar with the dictionary syntax, you can create a dictionary functionally with the dict() creator or literally with the dictionary syntax
# functionally
d = dict(spam=1, eggs=2)

#literally:
d = { 'spam': 1, 'eggs': 2 }
For classes
# functionally
A = type('A', (), {})

#literally
class A:
    pass
Having a functional way of doing things can be more suitable for classes that are automatically generated by a program instead of being hard coded.


RE: How does this code create a class? - Pedroski55 - Apr-21-2024

Thanks again, I appreciate it.

I only do simple things, I never felt the need to create a class, so I never delved into them.

Quote:When you have a class A, you can use A() as a function to create instances of A objects.

Now you are confusing me, but I am often confused, doesn't matter!


RE: How does this code create a class? - Gribouillis - Apr-21-2024

(Apr-21-2024, 05:08 AM)Pedroski55 Wrote: Now you are confusing me, but I am often confused, doesn't matter!
Yes, the word function is misleading. The accurate word for this is callable. A class is callable although it is not a function.

As an example of overuse of the class syntax, see this snippet where I create dictionaries with the class syntax instead of creating classes, so instead of the above code to create a dict, I can write
>>> class d(metaclass=just_a_dict):
...     spam = 1
...     eggs = 2
... 
>>> d
{'spam': 1, 'eggs': 2}  # d is a dictionary, not a class
This is crazy code, but it works.