(Mar-06-2020, 04:47 AM)michael1789 Wrote: Your major problem is that they aren't really classes
That statement is not true. This is valid code and they are classes all right. But I will come to that after I answer OP question.
The print function in class B get executed once and only once - at the time of class definition and only then, i.e. it will never be executed again. You are wrong in your assumption that class B print is executed at the time of instance creation (i.e. second).
The print function in class A
__init__()
method is executed every time when you create new instance of class A.
Now, I doubt you will ever see print function like the one in class B in real code. However you may see class attributes instead. Look at following example:
class Foo:
spam = 'This is class attribute spam' # this is class attribute shared between all class instances
eggs = [] # mutable class attribute
def __init__(self, message):
self.message = message # this is instance attribute
def do_something(self):
print('\nDoing something...')
Foo.spam = 'I did something'
Foo.eggs.append(self.message)
print(Foo.spam) # access the class attribute
foo = Foo('This is instance foo') # create instance foo
bar = Foo('This is instance bar') # create instance bar
print('\nAccess instance foo attributes after instantiation')
print(foo.spam)
print(foo.eggs)
print(foo.message)
print('\nAccess instance bar attributes after instantiation')
print(bar.spam)
print(bar.eggs)
print(bar.message)
# change class attribute and instance attribute
Foo.spam = 'New class spam'
foo.message = 'New foo message'
print('\nAccess instance foo attributes after change')
print(foo.spam)
print(foo.eggs)
print(foo.message)
print('\nAccess instance bar attributes after change')
print(bar.spam)
print(bar.eggs)
print(bar.message)
foo.do_something()
print('\nAccess instance foo attributes after call do_something()')
print(foo.spam)
print(foo.eggs)
print(foo.message)
print('\nAccess instance bar attributes after call do_something()')
print(bar.spam)
print(bar.eggs)
print(bar.message)
Output:
This is class attribute spam
Access instance foo attributes after instantiation
This is class attribute spam
[]
This is instance foo
Access instance bar attributes after instantiation
This is class attribute spam
[]
This is instance bar
Access instance foo attributes after change
New class spam
[]
New foo message
Access instance bar attributes after change
New class spam
[]
This is instance bar
Doing something...
Access instance foo attributes after call do_something()
I did something
['New foo message']
New foo message
Access instance bar attributes after call do_something()
I did something
['New foo message']
This is instance bar
@
michael1789, if the class is "doing" something does not qualify it as class or not. You can see code like this
class Foo:
pass
It may be because it's just a placeholder for a class that will be implemented later. Even before being implemented you can see other class inherit from it.
Another common use case is to define custom exceptions, e.g.
class MyError(Exception):
pass
def make_error():
raise MyError('This is custom error')
make_error()
Output:
Traceback (most recent call last):
File "/home/buran/sandbox/pyforum.py", line 50, in <module>
make_error()
File "/home/buran/sandbox/pyforum.py", line 48, in make_error
raise MyError('This is custom error')
__main__.MyError: This is custom error