|
| https://realpython.com/ |
| Start Here | https://realpython.com/start-here/ |
|
Learn Python
| https://realpython.com/lessons/python-attributes/ |
| Python Tutorials →In-depth articles and video courses | https://realpython.com/search?kind=article&kind=course&order=newest |
| Learning Paths →Guided study plans for accelerated learning | https://realpython.com/learning-paths/ |
| Quizzes & Exercises →Check your learning progress | https://realpython.com/quizzes/ |
| Browse Topics →Focus on a specific area or skill level | https://realpython.com/tutorials/all/ |
| Community Chat →Learn with other Pythonistas | https://realpython.com/community/ |
| Office Hours →Live Q&A calls with Python experts | https://realpython.com/office-hours/ |
| Podcast →Hear what’s new in the world of Python | https://realpython.com/podcasts/rpp/ |
| Books →Round out your knowledge and learn offline | https://realpython.com/products/books/ |
| Reference →Concise definitions for common Python terms | https://realpython.com/ref/ |
| Code Mentor →BetaPersonalized code assistance & learning tools | https://realpython.com/mentor/ |
| Unlock All Content → | https://realpython.com/account/join/ |
|
More
| https://realpython.com/lessons/python-attributes/ |
| Learner Stories | https://realpython.com/learner-stories/ |
| Python Newsletter | https://realpython.com/newsletter/ |
| Python Job Board | https://www.pythonjobshq.com |
| Meet the Team | https://realpython.com/team/ |
| Become a Tutorial Writer | https://realpython.com/write-for-us/ |
| Become a Video Instructor | https://realpython.com/become-an-instructor/ |
| Search | https://realpython.com/search |
| https://realpython.com/search |
| Join | https://realpython.com/account/join/ |
| Sign‑In | https://realpython.com/account/login/?next=%2Flessons%2Fpython-attributes%2F |
| Unlock This Lesson | https://realpython.com/account/join/?utm_source=rp_lesson&utm_content=python-class-object |
| Unlock This Lesson | https://realpython.com/account/join/?utm_source=rp_lesson&utm_content=python-class-object |
| https://realpython.com/courses/python-class-object/#team |
| Class Concepts: Object-Oriented Programming in Python | https://realpython.com/courses/python-class-object/ |
| Christopher Trudeau | https://realpython.com/courses/python-class-object/#team |
| Recommended Tutorial | https://realpython.com/python-classes/ |
| Course Slides (.pdf) | https://realpython.com/courses/python-class-object/downloads/python-class-object-slides/ |
| Sample Code (.zip) | https://realpython.com/courses/python-class-object/downloads/python-class-object-code/ |
| Ask a Question | https://realpython.com/lessons/python-attributes/#discussion |
| https://realpython.com/feedback/survey/course/python-class-object/liked/?from=lesson-title |
| https://realpython.com/feedback/survey/course/python-class-object/disliked/?from=lesson-title |
| Transcript | https://realpython.com/lessons/python-attributes/#transcript |
| Discussion | https://realpython.com/lessons/python-attributes/#discussion |
| 00:00 | https://realpython.com/lessons/python-attributes/#t=0.51 |
| In the previous lesson, I showed you how to write your first class in Python. | https://realpython.com/lessons/python-attributes/#t=0.51 |
| In this lesson, I’ll dive deeper in how you associate data with your object | https://realpython.com/lessons/python-attributes/#t=4.37 |
| through attributes. | https://realpython.com/lessons/python-attributes/#t=8.35 |
| 00:10 | https://realpython.com/lessons/python-attributes/#t=10.25 |
| So far, you’ve seen me use attributes on instantiated objects, | https://realpython.com/lessons/python-attributes/#t=10.25 |
| but Python actually supports two different kinds of attributes: | https://realpython.com/lessons/python-attributes/#t=14.17 |
| the instance ones that I just mentioned, and class attributes. | https://realpython.com/lessons/python-attributes/#t=17.77 |
| 00:23 | https://realpython.com/lessons/python-attributes/#t=23.19 |
| Instance attributes are specific to an object, | https://realpython.com/lessons/python-attributes/#t=23.19 |
| while class attributes are shared across all objects created from the same class. | https://realpython.com/lessons/python-attributes/#t=25.72 |
| Inside the class, | https://realpython.com/lessons/python-attributes/#t=31.33 |
| the instance attributes are assigned and accessed using dot notation on the self | https://realpython.com/lessons/python-attributes/#t=32.29 |
| reference, while class attributes are referenced directly on the class. | https://realpython.com/lessons/python-attributes/#t=37.43 |
| 00:42 | https://realpython.com/lessons/python-attributes/#t=42.31 |
| Let’s go look at some examples. | https://realpython.com/lessons/python-attributes/#t=42.31 |
| I’m going to create a new class that counts how many instance objects are | https://realpython.com/lessons/python-attributes/#t=45.2 |
| created from it, and I’m going to name it ObjectCounter. | https://realpython.com/lessons/python-attributes/#t=48.86 |
| 00:58 | https://realpython.com/lessons/python-attributes/#t=58.55 |
| Inside the class declaration block when I create an attribute this way, | https://realpython.com/lessons/python-attributes/#t=58.55 |
| it’s a class attribute. | https://realpython.com/lessons/python-attributes/#t=62.2 |
| That means it’ll be common across all object instances constructed from this | https://realpython.com/lessons/python-attributes/#t=64.52 |
| class. Remember, to get at an instance inside the class, | https://realpython.com/lessons/python-attributes/#t=69.29 |
| you need self, and there’s no self here, so it’s on the class instead. | https://realpython.com/lessons/python-attributes/#t=73.59 |
| 01:19 | https://realpython.com/lessons/python-attributes/#t=79.54 |
| Let’s write .__init__(). | https://realpython.com/lessons/python-attributes/#t=79.54 |
| 01:28 | https://realpython.com/lessons/python-attributes/#t=88.61 |
| Each time you create a new object, .__init__() gets called. | https://realpython.com/lessons/python-attributes/#t=88.61 |
| So this is a good place to increment the counter that counts how many instances | https://realpython.com/lessons/python-attributes/#t=92.24 |
| there are. To access the class attribute, | https://realpython.com/lessons/python-attributes/#t=96.43 |
| I use the name of the class instead of self, | https://realpython.com/lessons/python-attributes/#t=99.66 |
| and then here I’m incrementing its value by one. | https://realpython.com/lessons/python-attributes/#t=102.64 |
| 01:46 | https://realpython.com/lessons/python-attributes/#t=106.59 |
| Let me instantiate an object … | https://realpython.com/lessons/python-attributes/#t=106.59 |
| 01:52 | https://realpython.com/lessons/python-attributes/#t=112.33 |
| and there it is. | https://realpython.com/lessons/python-attributes/#t=112.33 |
| That ugly bit of REPL response is because I haven’t defined how to represent | https://realpython.com/lessons/python-attributes/#t=113.5 |
| this object. The default display shows the name of the class, | https://realpython.com/lessons/python-attributes/#t=117.87 |
| the module it’s in (__main__), and a reference address. | https://realpython.com/lessons/python-attributes/#t=121.81 |
| 02:09 | https://realpython.com/lessons/python-attributes/#t=129.06 |
| An object inherits the attributes of its class, | https://realpython.com/lessons/python-attributes/#t=129.06 |
| so you can access the .num_instances attribute through the object. | https://realpython.com/lessons/python-attributes/#t=132.54 |
| Let’s create two. | https://realpython.com/lessons/python-attributes/#t=137.1 |
| 02:24 | https://realpython.com/lessons/python-attributes/#t=144.97 |
| And the .num_instances counter has been incremented, | https://realpython.com/lessons/python-attributes/#t=144.97 |
| 02:31 | https://realpython.com/lessons/python-attributes/#t=151.0 |
| and as the value is on the class and not on the object, | https://realpython.com/lessons/python-attributes/#t=151.0 |
| it’s shared across all the objects. | https://realpython.com/lessons/python-attributes/#t=154.13 |
| Accessing it on one shows the same result as accessing it on two. | https://realpython.com/lessons/python-attributes/#t=156.65 |
| 02:46 | https://realpython.com/lessons/python-attributes/#t=166.16 |
| And now that I’ve shown you you can do that, | https://realpython.com/lessons/python-attributes/#t=166.16 |
| I’m going to tell you that you shouldn’t. Generally speaking, | https://realpython.com/lessons/python-attributes/#t=168.52 |
| I prefer to use the class name when accessing class attributes. | https://realpython.com/lessons/python-attributes/#t=171.58 |
| 02:55 | https://realpython.com/lessons/python-attributes/#t=175.44 |
| It makes it clearer that what you’re using is a class attribute, and it | https://realpython.com/lessons/python-attributes/#t=175.44 |
| also avoids a subtle mistake. And what mistake is that you might ask. | https://realpython.com/lessons/python-attributes/#t=180.28 |
| Good question. Follow along. | https://realpython.com/lessons/python-attributes/#t=185.71 |
| 03:08 | https://realpython.com/lessons/python-attributes/#t=188.9 |
| You’ve seen class attributes can be accessed through the object, and you saw | https://realpython.com/lessons/python-attributes/#t=188.9 |
| that the class attribute is modified through the class, | https://realpython.com/lessons/python-attributes/#t=193.68 |
| but it’s important to note that it can only be modified through the class. | https://realpython.com/lessons/python-attributes/#t=197.5 |
| 03:22 | https://realpython.com/lessons/python-attributes/#t=202.91 |
| You see, | https://realpython.com/lessons/python-attributes/#t=202.91 |
| Python supports the dynamic addition of attributes to an object, not just | https://realpython.com/lessons/python-attributes/#t=203.29 |
| in .__init__(), but anywhere you have access to the object. | https://realpython.com/lessons/python-attributes/#t=208.21 |
| 03:32 | https://realpython.com/lessons/python-attributes/#t=212.18 |
| Python also supports overriding values. | https://realpython.com/lessons/python-attributes/#t=212.18 |
| When you assign an attribute on an object, | https://realpython.com/lessons/python-attributes/#t=215.87 |
| Python sees this as being an object attribute. | https://realpython.com/lessons/python-attributes/#t=218.06 |
| If you already have a class attribute with the same name, it gets overridden, | https://realpython.com/lessons/python-attributes/#t=221.66 |
| hence the subtle bug. | https://realpython.com/lessons/python-attributes/#t=226.69 |
| 03:48 | https://realpython.com/lessons/python-attributes/#t=228.34 |
| You might think you’re changing the value of the shared attribute, | https://realpython.com/lessons/python-attributes/#t=228.34 |
| but you’re not. | https://realpython.com/lessons/python-attributes/#t=231.02 |
| You’re creating a new one on the object that happens to have the same name and | https://realpython.com/lessons/python-attributes/#t=231.82 |
| overriding it. | https://realpython.com/lessons/python-attributes/#t=236.65 |
| 03:58 | https://realpython.com/lessons/python-attributes/#t=238.51 |
| Let’s go look at an example of this fiasco in practice. | https://realpython.com/lessons/python-attributes/#t=238.51 |
| Same class as before. | https://realpython.com/lessons/python-attributes/#t=243.37 |
| There’s my object. | https://realpython.com/lessons/python-attributes/#t=247.47 |
| And like before, I can access the class attribute on the object. And | https://realpython.com/lessons/python-attributes/#t=251.32 |
| 04:20 | https://realpython.com/lessons/python-attributes/#t=260.43 |
| as a reminder, that’s the preferred way: doing it on the class itself. | https://realpython.com/lessons/python-attributes/#t=260.43 |
| I mentioned I can assign attributes on objects dynamically. | https://realpython.com/lessons/python-attributes/#t=264.99 |
| Here, I’ve added a new one called .value, | https://realpython.com/lessons/python-attributes/#t=270.77 |
| and it’s an attribute just like anything else. | https://realpython.com/lessons/python-attributes/#t=275.25 |
| 04:37 | https://realpython.com/lessons/python-attributes/#t=277.49 |
| You don’t have to do it inside of .__init__() in order to assign a new | https://realpython.com/lessons/python-attributes/#t=277.49 |
| attribute. | https://realpython.com/lessons/python-attributes/#t=281.38 |
| 04:46 | https://realpython.com/lessons/python-attributes/#t=286.38 |
| Here, I’ve done the exact same thing. | https://realpython.com/lessons/python-attributes/#t=286.38 |
| I’ve created a .num_instances attribute and added a value dynamically. | https://realpython.com/lessons/python-attributes/#t=289.46 |
| Since it has the same name as the class attribute, | https://realpython.com/lessons/python-attributes/#t=294.64 |
| the object’s attribute takes precedence. So | https://realpython.com/lessons/python-attributes/#t=297.37 |
| the class attribute hasn’t changed, | https://realpython.com/lessons/python-attributes/#t=304.22 |
| 05:10 | https://realpython.com/lessons/python-attributes/#t=310.31 |
| but the object attribute is 85. | https://realpython.com/lessons/python-attributes/#t=310.31 |
| This would be why I prefer to use the class name. | https://realpython.com/lessons/python-attributes/#t=313.93 |
| It’s clearer and avoids this problem. | https://realpython.com/lessons/python-attributes/#t=317.09 |
| If you don’t have the class handy (say it’s declared in another file), | https://realpython.com/lessons/python-attributes/#t=320.52 |
| you can get at an object’s class through the .__class__ attribute. | https://realpython.com/lessons/python-attributes/#t=324.6 |
| 05:29 | https://realpython.com/lessons/python-attributes/#t=329.8 |
| And as that’s the object’s class, you can get at its attributes from there. | https://realpython.com/lessons/python-attributes/#t=329.8 |
| See? Although Python doesn’t stop you from accessing class attributes from the | https://realpython.com/lessons/python-attributes/#t=335.93 |
| object, it’s a good habit to strictly access them from the class itself to avoid | https://realpython.com/lessons/python-attributes/#t=340.27 |
| confusion. If you’re coming to Python from a strictly typed | https://realpython.com/lessons/python-attributes/#t=344.7 |
| compiled object-oriented language, | https://realpython.com/lessons/python-attributes/#t=349.48 |
| I suspect you’re thinking this is a giant foot gun. | https://realpython.com/lessons/python-attributes/#t=351.52 |
| 05:55 | https://realpython.com/lessons/python-attributes/#t=355.04 |
| I will admit on occasion I accidentally add a new attribute because I misspelled | https://realpython.com/lessons/python-attributes/#t=355.04 |
| the attribute I wanted. | https://realpython.com/lessons/python-attributes/#t=359.64 |
| A compiled language definitely catches these kinds of problems. | https://realpython.com/lessons/python-attributes/#t=361.44 |
| 06:05 | https://realpython.com/lessons/python-attributes/#t=365.63 |
| The other side of that coin, though, is some truly powerful things can be done | https://realpython.com/lessons/python-attributes/#t=365.63 |
| with the dynamic nature of Python. | https://realpython.com/lessons/python-attributes/#t=369.49 |
| A lot of the magic behind SQLAlchemy and Django’s ORM and how they map to | https://realpython.com/lessons/python-attributes/#t=371.61 |
| databases is built on top of the dynamic nature of Python, | https://realpython.com/lessons/python-attributes/#t=376.81 |
| so you gain some power at the risk of certain kinds of bugs. | https://realpython.com/lessons/python-attributes/#t=381.07 |
| 06:24 | https://realpython.com/lessons/python-attributes/#t=384.68 |
| Whether that’s worth that trade-off is for you to decide when you’re picking | https://realpython.com/lessons/python-attributes/#t=384.68 |
| your language for your project. | https://realpython.com/lessons/python-attributes/#t=388.68 |
| You’ve seen how classes and objects have attributes and methods. | https://realpython.com/lessons/python-attributes/#t=391.97 |
| 06:35 | https://realpython.com/lessons/python-attributes/#t=395.77 |
| In the next lesson, | https://realpython.com/lessons/python-attributes/#t=395.77 |
| I’ll dive deeper to show you properties, Python’s equivalent of getters | https://realpython.com/lessons/python-attributes/#t=396.9 |
| and setters. | https://realpython.com/lessons/python-attributes/#t=401.81 |
| Become a Member | https://realpython.com/account/join/ |
| https://realpython.com/lessons/python-class-creation/ |
| Overview | https://realpython.com/courses/python-class-object/ |
| https://realpython.com/lessons/python-properties-and-descriptors/ |
|
Class Concepts: Object-Oriented Programming in Python (Overview) 03:22
| https://realpython.com/videos/python-class-object-overview/ |
|
The Case for Object-Oriented Programming 09:55
| https://realpython.com/videos/why-oop-python/ |
|
Class Creation 09:43
| https://realpython.com/lessons/python-class-creation/ |
|
Attributes 06:44
| https://realpython.com/lessons/python-attributes/ |
|
Properties and Descriptors 07:51
| https://realpython.com/lessons/python-properties-and-descriptors/ |
|
Class Methods 08:19
| https://realpython.com/lessons/python-methods/ |
|
A Complete Example: Putting It All Together 10:22
| https://realpython.com/lessons/python-class-object-review/ |
|
Class Concepts: Object-Oriented Programming in Python (Summary) 04:34
| https://realpython.com/lessons/python-class-object-summary/ |
| Privacy Policy | https://realpython.com/privacy-policy/ |
Viewport: width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover