Pythonoop Tutorial: Classes and Instances

Python is a very flexible language that supports multiple programming paradigms such as procedural, functional and object-oriented (OOP). When the project scale gradually expands, oop becomes a powerful tool for organizing complex code and improving maintainability. In the world of OOP, Class and Instance are the two most basic concepts that must be mastered.


1. Life analogy: drawings and objects

To clarify the difference between classes and instances, you might as well leave the code and look at examples in life:

  • A car design drawing is like a "class" - it defines "the attributes a car should have" (brand, color, number of wheels) and "the actions a car can perform" (start, brake, whistle).
  • The red Tesla Model 3 parked downstairs is an "example" - it is a tangible product that is manufactured according to the drawings, has its own unique license plate number and color, and can truly perform all the actions described on the drawings.

Translate this kind of thinking into programming:

  • Class is abstract data + behavior template, data is called attributes, and behavior is called methods.
  • Instance is a specific object generated based on a template. The properties of each instance can be different, but they share all methods defined in the class.

2. Define your first class

In Python, useclasskeyword to define a class. In modern Python (3.x), all classes inherit fromobject, there is no need to write it out explicitly(object), the simplest way to write it is as follows:

# 定义一个没有任何属性和方法的“空”学生类
class Student:
    pass   # pass是占位符,用来保证语法正确

AlthoughStudentThe class can't currently do anything, but it is already a legal "template".


3. Generate instances from templates

Creating an instance is as simple as calling a function: class name + parentheses.

# 用Student类“生”出两个具体的学生
bart = Student()
lisa = Student()

# 每个实例在内存中都有独立的位置
print(bart)    # <__main__.Student object at 0x7f...>
print(lisa)    # <__main__.Student object at 0x7f...>

# 类本身是一个“类型对象”
print(Student) # <class '__main__.Student'>

As you can see,bartandlisaAllStudentInstances of the class, but they occupy different memory addresses and are two completely independent objects.


4. Use__init__Assign initial properties

An empty instance is obviously of no use. We hope that when creating an instance, it will have some attributes (such as name, grades). This requires the use of a "magic method" in Python——__init__

__init__The method is automatically called after the instance is created, so it is often called constructor or initialization method. Pay attention to the naming: there are two underscores before and after.

class Student:
    # self 必须放在参数的第一个位置,它代表“当前正在被创建的实例”
    def __init__(self, name, score):
        # 通过 self.xxx 绑定的属性,会成为该实例的专属属性
        self.name = name
        self.score = score

Three important points when writing:

  1. selfThe parameters must be written explicitly, but Python will automatically pass them in when calling, and we do not need to manually assign values ​​to them.
  2. __init__The name cannot be wrong. One more or one less underscore will invalidate it.
  3. When creating an instance, in addition toselfParameters outside must correspond to the definition one-to-one.

Test it out:

bart = Student('Bart Simpson', 59)
print(bart.name)   # Bart Simpson
print(bart.score)  # 59

for each instancenameandscoreThey are all stored independently and do not interfere with each other.


5. Let the instance have "behavior": instance method

In addition to static properties, we usually also need to enable instances to perform certain operations, which are called methods. The most commonly used method type is instance method, and its first parameter must also beself, so that you can access the properties of the current instance.

5.1 Define the method of printing results

class Student:
    def __init__(self, name, score):
        self.name = name
        self.score = score

    # 实例方法:利用 self 拿到当前实例的 name 和 score
    def print_score(self):
        print(f"{self.name} 的分数是 {self.score}")

5.2 Calling methods

There is still no need to pass when callingself, Python will automatically transfer the caller (such asbart) is bound toselfsuperior:

bart = Student('Bart Simpson', 59)
bart.print_score()   # Bart Simpson 的分数是 59

6. The core advantage of object-oriented: data encapsulation

In object-less programming, data is often separated from the functions that operate on the data, which increases the risk of the data being accidentally modified or misused. Data encapsulation packages "properties" and "methods to operate these properties" together, logically forming a self-contained unit. External users only need to call methods and do not need to directly touch the underlying data.

6.1 Encapsulate a grade calculation function

we canStudentAdd one to the classget_gradeMethod that returns the rank based on the score. Users do not need to care about the internal judgment logic at all.

class Student:
    def __init__(self, name, score):
        self.name = name
        self.score = score

    def print_score(self):
        print(f"{self.name} 的分数是 {self.score}")

    def get_grade(self):
        if self.score >= 90:
            return 'A'
        elif self.score >= 60:
            return 'B'
        else:
            return 'C'

6.2 External calling experience

lisa = Student('Lisa Simpson', 99)
bart = Student('Bart Simpson', 59)

# 只需一行调用,内部细节被完美隐藏
print(lisa.name, lisa.get_grade())   # Lisa Simpson A
print(bart.name, bart.get_grade())   # Bart Simpson C

The advantage of this is that if the rules for rating assessment change in the future, we only need to modifyget_gradeThe internal implementation of the method will automatically take effect wherever this method is used.


7. Python’s “stunt”: dynamic attributes

Unlike languages ​​such as Java and C++, Python allows you to dynamically add, modify, or delete attributes to a specific instance at runtime. These properties belong only to that instance and do not affect the class and other instances.

bart = Student('Bart Simpson', 59)
lisa = Student('Lisa Simpson', 87)

# 只给 bart 增加一个 age 属性
bart.age = 8
print(bart.age)   # 8

# lisa 并没有这个属性,访问会报错
print(lisa.age)   # AttributeError: 'Student' object has no attribute 'age'

🧠 Tips Although dynamic attributes are flexible, excessive use will make the code logic difficult to trace and may easily lead to hidden bugs. If a property is required for all instances, MUST put it in__init__Initialized uniformly.


8. Coding style and best practices

Writing "usable" code is just the beginning. Writing "easy-to-read and easy-to-maintain" code is professional performance. Below are some norms commonly followed by the Python community.

8.1 Naming Convention

  • Class name: Use PascalCase (large camel case), for exampleStudentUniversityStudent
  • Function name, method name, variable name: use snake_case (lowercase underline), for examplebart_simpsonprint_score

8.2 Make good use of type hints and docstrings

Python 3.5+ supports type hints. Although it does not force checking at runtime, it can significantly improve code readability and make the IDE's auto-completion more intelligent. Paired with well-commented docstrings, your class will be like a gadget with its own instructions.

class Student:
    """学生类,管理学生的基本信息和成绩"""

    def __init__(self, name: str, score: float) -> None:
        """
        初始化学生实例

        Args:
            name: 学生姓名
            score: 考试分数
        """
        self.name = name
        self.score = score

    def print_score(self) -> None:
        """打印姓名和成绩"""
        print(f"{self.name} 的分数是 {self.score}")

    def get_grade(self) -> str:
        """
        根据分数返回等级

        Returns:
            'A': 90分及以上
            'B': 60-89分
            'C': 60分以下
        """
        if self.score >= 90:
            return 'A'
        elif self.score >= 60:
            return 'B'
        else:
            return 'C'

9. Summary

Through this article, we quickly completed the road to enlightenment in Pythonoop. The core points are summarized as follows:

  1. Class is an abstract template, and Instance is a specific product;
  2. __init__The constructor is responsible for setting independent initial properties for each instance;
  3. Instance method passedselfAccess instance data and implement object behavior;
  4. Data encapsulation binds properties and methods together to improve the security and maintainability of the code;
  5. Dynamic attributes give Python unique flexibility, but should be used with caution.

Once you master classes and instances, you have a solid foundation for building more complex OOP structures (inheritance, polymorphism, private properties, etc.). We will continue to delve deeper in the next articles, so stay tuned!