Objects in Python: Integer, Float, List & Classes

  • Thread starter fog37
  • Start date
  • Tags
    Python
In summary: Car()#print the type of mycarprint(type(mycar))<class '__main__.Car'>#print the type of mycar with the __init__ methodmycar= Car(brand="Honda", model="Altima", color="green")print(type(mycar))<class '__main__.Car__init__'>In summary, the Car class has three attributes, brand, model, and color. The turn_on() and turn_off
  • #1
fog37
1,568
108
Hello,
I get that everything (almost?) in Python is an object. Objects are instances of classes with associated attributes (i.e. characteristics, properties, features) which are essentially variables. Objects also have associated methods (i.e. functions that act on the object or make the object do certain things). Each class has its own innate methods.

That said:
  • If "everything" is an object, does that mean that even a simply integer, float, or list that we create at the prompt is an object? From what class do these objects originate?
  • The built-in functions from the Python standard library, like the functions like print() or input(), are therefore methods, not objects, correct? Methods are not objects. To what class do the built-in functions/methods belong to?
  • When creating a class, the special method __init__ (the constructor) is almost always used to create objects. But I don't think it is always needed to create an object from a class. For example, let's consider the class Car and create a single object from it:
Code:
# Create a simple class with a single attribute

class Car():
model = "Honda"

mycar=Car() # Here we instantiate an object called mycar from the class. This object has a single attribute already specified.
print(mycar.model) # we use the dot notation to view the attribute associated to the object mycar.

# We could write the same class Car  with 3 attributes in a different way using the __int__ method:

class Car():
    def __init__(self, make, model, color) : # make, model, color are threeattributes
    self.make = make
    self.model = model
    self.color = color

mycar= Car(Nissan,Altima, green)    #this line creates an object called mycar and we assign the values to the attributes at this moment

The difference: at line #17 we created an object and assigned values to its attributes at the moment of instantiation. In the first case instead (line #3 and line #4) we assigned the value to the attribute model not when we created the object but when we created the class...

Is that correct? And is that why using the method __init__ is useful when creating objects?Thank you for any clarifications!
 
Technology news on Phys.org
  • #2
fog37 said:
Hello,
I get that everything (almost?) in Python is an object. Objects are instances of classes with associated attributes (i.e. characteristics, properties, features) which are essentially variables. Objects also have associated methods (i.e. functions that act on the object or make the object do certain things). Each class has its own innate methods.

That said:
  • If "everything" is an object, does that mean that even a simply integer, float, or list that we create at the prompt is an object? From what class do these objects originate?
  • The built-in functions from the Python standard library, like the functions like print() or input(), are therefore methods, not objects, correct? Methods are not objects. To what class do the built-in functions/methods belong to?
  • When creating a class, the special method __init__ (the constructor) is almost always used to create objects. But I don't think it is always needed to create an object from a class. For example, let's consider the class Car and create a single object from it:
Code:
# Create a simple class with a single attribute

class Car():
model = "Honda"

mycar=Car() # Here we instantiate an object called mycar from the class. This object has a single attribute already specified.
print(mycar.model) # we use the dot notation to view the attribute associated to the object mycar.

# We could write the same class Car  with 3 attributes in a different way using the __int__ method:

class Car():
    def __init__(self, make, model, color) : # make, model, color are threeattributes
    self.make = make
    self.model = model
    self.color = color

mycar= Car(Nissan,Altima, green)    #this line creates an object called mycar and we assign the values to the attributes at this moment

The difference: at line #17 we created an object and assigned values to its attributes at the moment of instantiation. In the first case instead (line #3 and line #4) we assigned the value to the attribute model not when we created the object but when we created the class...

Is that correct? And is that why using the method __init__ is useful when creating objects?Thank you for any clarifications!
did you try to compile and run the code?what was the output?
 
  • #3
You can see this by printing out the 'type' of an object. So below you can see that an integer is an object of class 'int', and a method like print() belongs to class 'builtin_function_or_method'.
Python:
>>> class Car():
...     model = "Honda"
...
>>> mycar=Car()
>>> print(type(mycar))
<class '__main__.Car'>
>>> x = 7
>>> print(type(x))
<class 'int'>
>>> print(type(print))
<class 'builtin_function_or_method'>
 
  • Like
Likes fog37
  • #4
I tried the following two classes, one with and the other without the __init__ method:

CODE 1
Code:
class Car:

brand = ""
model = ""
color = ""

def turn_on(self)
    print("the car turns on")
  
def accelerate(self)
    print("the car is accelerating")

# Now I will create two objects, car1 and car2
car1=Car()
car2=Car()

# I can assign values to the attributes at this point
car1.brand= "Honda"
car2.brand = "Mazda"
car1.color="Green"
car2.color = "Red"

Using the code above, I created objects after having created the class.

CODE 2
Code:
# class Car:
brand = None
color= None

def __init__(self):
car1 = Car()
car2 = Car()

def turn_on(self)
    print("the car turns on")
  
def accelerate(self)
    print("the car is accelerating")

I am getting the same result...
 
  • #5
fog37 said:
If "everything" is an object, does that mean that even a simply integer, float, or list that we create at the prompt is an object?

Yes.

fog37 said:
From what class do these objects originate?

From the built-in types int, float, and list. The objects you create at the prompt are instances of those types. Note that you could even explicitly use the types in creating the objects; for example, you could say...

Python:
i = int(1)
f = float(0.5)
l = list([1, 2, 3])

...and it would give the same results as...

Python:
i = 1
f = 0.5
l = [1, 2, 3]

The Python interpreter automatically interprets those literals as the corresponding types, so you don't have to specify the types explicitly (which is why nobody bothers to, since it's just extra typing that's not needed).

fog37 said:
The built-in functions from the Python standard library, like the functions like print() or input(), are therefore methods, not objects, correct?

No. They are function objects (yes, functions are objects too). They are not methods because they are not in any type's namespace; they are in the global built-in namespace.

fog37 said:
To what class do the built-in functions/methods belong to?

They don't belong to any class. See above.

fog37 said:
When creating a class, the special method __init__ (the constructor) is almost always used to create objects. But I don't think it is always needed to create an object from a class.

That's correct; when you define a class, you don't need to give it an __init__ method. If you don't, an instance of the class will be initialized with no attributes, i.e., with an empty instance namespace.

fog37 said:
Is that correct?

Yes; Python let's you assign attributes to an object instance that weren't defined in the class definition for the class that the object is an instance of.

fog37 said:
is that why using the method __init__ is useful when creating objects?

It's one common reason why the __init__ method is used, yes. It's not the only one, though.
 
  • Like
Likes fog37
  • #6
fog37 said:
I tried the following two classes, one with and the other without the __init__ method:

CODE 1
Code:
class Car:

brand = ""
model = ""
color = ""

def turn_on(self)
    print("the car turns on")

def accelerate(self)
    print("the car is accelerating")

# Now I will create two objects, car1 and car2
car1=Car()
car2=Car()

# I can assign values to the attributes at this point
car1.brand= "Honda"
car2.brand = "Mazda"
car1.color="Green"
car2.color = "Red"

Using the code above, I created objects after having created the class.

CODE 2
Code:
# class Car:
brand = None
color= None

def __init__(self):
car1 = Car()
car2 = Car()

def turn_on(self)
    print("the car turns on")

def accelerate(self)
    print("the car is accelerating")

I am getting the same result...

Do you try executing these codes before you post? Apparently not since there are several syntax errors. The indenting is wrong, and you are missing the colons at the ends of the 'def' lines. Try cleaning up Code2 and executing it. What happens?
 
  • Like
Likes fog37 and berkeman
  • #7
phyzguy said:
Do you try executing these codes before you post? Apparently not since there are several syntax errors. The indenting is wrong, and you are missing the colons at the ends of the 'def' lines. Try cleaning up Code2 and executing it. What happens?
Thank you. I will rerun it today and show the results
 
  • #8
PeterDonis said:
Yes.
From the built-in types int, float, and list. The objects you create at the prompt are instances of those types. Note that you could even explicitly use the types in creating the objects; for example, you could say...

Python:
i = int(1)
f = float(0.5)
l = list([1, 2, 3])

...and it would give the same results as...

Python:
i = 1
f = 0.5
l = [1, 2, 3]

The Python interpreter automatically interprets those literals as the corresponding types, so you don't have to specify the types explicitly (which is why nobody bothers to, since it's just extra typing that's not needed).
No. They are function objects (yes, functions are objects too). They are not methods because they are not in any type's namespace; they are in the global built-in namespace.
They don't belong to any class. See above.
That's correct; when you define a class, you don't need to give it an __init__ method. If you don't, an instance of the class will be initialized with no attributes, i.e., with an empty instance namespace.
Yes; Python let's you assign attributes to an object instance that weren't defined in the class definition for the class that the object is an instance of.
It's one common reason why the __init__ method is used, yes. It's not the only one, though.
Thank you PeterDonis.

In summary, using the constructor ___init___ is not mandatory to create objects and their specific attributes.
The constructor __init__ provides "uniformity" in the sense that all objects created from the particular class will have exactly the same methods and attributes. Otherwise, we could create attributes for a certain object after creating the class and object itself, I believe. Different objects could have different attributes...

I don't think we could create methods, though, after creating the class or the object...
 
  • #9
fog37 said:
In summary, using the constructor ___init___ is not mandatory to create objects and their specific attributes.
Correct.

fog37 said:
The constructor __init__ provides "uniformity" in the sense that all objects created from the particular class will have exactly the same methods and attributes.
No. The constructor is simply a method that is called when an object is created, it does exactly what the code you put in it does, no more and no less.

fog37 said:
Otherwise, we could create attributes for a certain object after creating the class and object itself, I believe. Different objects could have different attributes...
'Otherwise' doesn't make any sense here. You can attach attributes to any object after it is created regardless of whether you define a custom constructor or not.

fog37 said:
I don't think we could create methods, though, after creating the class or the object...
Well you can (using the descriptor protocol), but I suggest you do a bit more practical programming with Python before you go deeper into the theory.
 
  • #10
fog37 said:
I don't think we could create methods, though, after creating the class or the object...

Yes, you can. You can define a function and assign it to a class, and it will work just like a method defined in the class statement block. The following code shows assigning both a method to a class after the class is defined, and assigning an attribute to an instance after the instance is created.

Python:
class Test:
    pass

def test_method(self):
    print(self.name)

Test.test_method = test_method

t = Test()
t.name = "Test name."
t.test_method()  # prints "Test name."

pbuk said:
you can (using the descriptor protocol),

You can use that too, yes, but you don't need to. See above.
 
  • #11
PeterDonis said:
The following code shows assigning both a method to a class after the class is defined, and assigning an attribute to an instance after the instance is created.
But it doesn't show assigning a method to an instance after the instance is created, for that you need the descriptor protocol. See modified code below or at https://repl.it/@pbuk/DescriptorProtocol

Python:
class Test:
    pass

def test_method(self):
    print(self.name)

Test.test_method = test_method

t = Test()
t.name = "Test name."
t.test_method()  # prints "Test name."

# Trying to bind a method to an instance:
t.unbound_method = test_method
try:
    t.unbound_method()
except TypeError:
    print("That didn't work")

# To bind a method to an instance you need to use the
# descriptor protocol:
t.bound_method = test_method.__get__(t)
t.bound_method()  # prints "Test name."
 
  • #12
pbuk said:
it doesn't show assigning a method to an instance after the instance is created, for that you need the descriptor protocol.

That's one way to do it, yes. Another way is to use functools.partial:

Python:
import functools

class Test:
    pass

def test_method(self):
    print(self.name)

t = Test()
t.name = "Test name."
t.test_method = functools.partial(test_method, t)

t.test_method()  # prints "Test name."

Note that both of these only assign the method to that particular instance of the class. If you want the method to be accessible to every instance of the class, you need to assign it to the class as I did before.
 
  • #13
PeterDonis said:
Another way is to use functools.partial

And yet another way is to use types.MethodType:

Python:
import types

class Test:
    pass

def test_method(self):
    print(self.name)

t = Test()
t.name = "Test name."
t.test_method = types.MethodType(test_method, t)

t.test_method()  # prints "Test name."
 
  • #14
fog37 said:
Thank you. I will rerun it today and show the results
So @fog37 , what happened when you ran your Code2?
 
  • #15
Hi phyzguy. This is what I tried:

Code:
class Car:
    brand = ""     # 1st empty attribute
    model = ""    # 1st empty attribute
    color = ""      # 1st empty attribute
   
    def turn_on(self)
    print("the car turns on")

I wrote the same class this time using the __init__ method:
Code:
[CODE]class Car:
# Here we use the __init__ method to set up how an object's feature (its attributes) will be:

    def __init__(self, brand,model,color)
    self.brand = brand
    self.model = model
    self.color = color

    def turn_on(self)
    print("the car turns on")

I don't fully appreciate the difference between the two codes. The 2nd code with __init__ seems to force all objects created from the class to have specific attributes from the get go. But in the first code we do create the same three attributes though... I also noticed that I am not specifying if the attributes are integers, string, etc. I guess the data type does not play a role?

Here the first code being executed:
1599827449644.png


I read that when an attribute (same thing as field?) is declared outside of the constructor __init__, it is called a "class attribute" instead of an "instance attribute".
 
  • #16
@fog37 , the __init__ function is executed whenever you create a new instance. I was trying to get you to execute your Code2 from post #6. If you try it, you will see that it leads to an infinite recursion. Do you see why?
 
  • Like
Likes fog37
  • #17
Thanks. I will go back and run that specific code.

But how about the two codes I just posted? What difference would it make to do one or the other?
 
  • #18
fog37 said:
Thanks. I will go back and run that specific code.

But how about the two codes I just posted? What difference would it make to do one or the other?
The point of the constructor is to be able to assign instance attributes when the instance is created.
Python:
myCar = Car("Aston Martin", "DB5", "silver")
 
  • Like
Likes fog37
  • #19
To be honest, I didn't know you could define the class attributes ouside of the init function like you did in you first code. I always use the init function. I think it is cleaner and more clear what you are doing. In your second code, when you instantiate an instance, you define the attributes when you call the class, like this: car1 = Car("Honda", "Civic", "red") . In your first example, whatever you defined for the brand, etc. is buried in the class definition and not easily accessible.
 
  • Like
Likes fog37
  • #20
pbuk said:
The point of the constructor is to be able to assign instance attributes when the instance is created.
Python:
myCar = Car("Aston Martin", "DB5", "silver")
Ok. I see. Without the constructor (my Code #1), we still have created empty class attributes which we can modify in content later. So the constructor is convenience...
 
  • #21
phyzguy said:
To be honest, I didn't know you could define the class attributes ouside of the init function like you did in you first code. I always use the init function.

The attributes defined directly in the class block, outside any method definition, belong to the class, not the instance. Attributes assigned to self inside a metbod belong to the instance, since that's what self refers to.
 
  • Like
Likes fog37 and phyzguy
  • #22
fog37 said:
I don't fully appreciate the difference between the two codes.

Per my previous post, the first one assigns attributes to the class. The second assigns attributes to the particular instance of the class that is being initialized.

To see the difference, consider the following transcript of an interactive Python interpreter session:

Python:
>>> class Test:
...     brand = ""
...
>>> Test.brand
''
>>> t = Test()
>>> t.brand
''
>>> t1 = Test()
>>> t1.brand = "Honda"
>>> t1.brand
'Honda'
>>> Test.brand
''
>>> t.brand
''
>>> Test.brand = "Default"
>>> Test.brand
'Default'
>>> t.brand
'Default'
>>> t1.brand
'Honda'

Notice that, first, setting the attribute on an instance overrides the attribute set on the class, but the attribute set on the class is still there, and still appears as an attribute of any instances where it hasn't been overridden. This is a common way to set default values for an attribute, which some class instances might override, but others won't.
 
  • Like
Likes phyzguy
  • #23
Does it matter what it's called? If you can write a program in any language and it works when you run it, who cares? Years ago, I ran a whole lot of electronic test equipment to do fairly complex testing by programming in Hewlett Packard Extended Basic. It made absolutely no difference whether I knew what things were called, I just knew how to use them.
 
  • #24
darth boozer said:
Does it matter what it's called? If you can write a program in any language and it works when you run it, who cares? Years ago, I ran a whole lot of electronic test equipment to do fairly complex testing by programming in Hewlett Packard Extended Basic. It made absolutely no difference whether I knew what things were called, I just knew how to use them.
I don't know anything about HP Extended Basic, but if it's not much more complex than plain old Basic, it does make a difference knowing what things are called. Modern programming languages are much more intricate than Basic of 40 or 50 years ago. The topic of this thread was concerned with the difference between a class attribute and an object attribute -- an attribute of an instance of a class.

If you are unaware of the difference between a class and an instance of a class, you won't be able to make any sense of what is being discussed in the thread. So that's why someone might care about what things are called.
 

What is an integer in Python?

An integer in Python is a data type that represents whole numbers. It can be positive or negative, and there is no limit to its size.

What is a float in Python?

A float in Python is a data type that represents decimal numbers. It is used to store numbers with a fractional component.

What is a list in Python?

A list in Python is a data structure that is used to store a collection of items. It can hold different types of data, such as integers, floats, and even other lists. Lists are mutable, meaning they can be changed after they are created.

What is a class in Python?

A class in Python is a blueprint for creating objects. It contains properties and methods that define the behavior of the objects created from it. Classes allow for code reusability and help to organize code in a more structured manner.

How do you create an object in Python?

To create an object in Python, you first need to define a class. Then, you can use the class to create an object by calling the class name followed by parentheses. This will create an instance of the class, which can then be used to access its properties and methods.

Similar threads

  • Programming and Computer Science
Replies
4
Views
1K
  • Programming and Computer Science
Replies
2
Views
1K
  • Programming and Computer Science
Replies
25
Views
3K
  • Programming and Computer Science
Replies
7
Views
946
  • Programming and Computer Science
Replies
3
Views
1K
  • Programming and Computer Science
Replies
1
Views
1K
  • Programming and Computer Science
Replies
1
Views
284
  • Programming and Computer Science
Replies
5
Views
785
  • Programming and Computer Science
Replies
9
Views
2K
  • Programming and Computer Science
Replies
9
Views
908
Back
Top