--- title: Object Oriented Programming fid: 20240128-192934 tags: url: https://realpython.com/python3-object-oriented-programming/ --- (Object-Oriented-Programming)= # Object Oriented Programming 2024-01-28 From: [Object-Oriented Programming (OOP) in Python 3 – Real Python](https://realpython.com/python3-object-oriented-programming/) - 定义一个类,它就像是创建对象的蓝图 - 使用类创建新对象 - 具有类继承功能的模型系统 ## 管理代码的困难 ```python kirk = ["James Kirk", 34, "Captain", 2265] spock = ["Spock", 35, "Science Officer", 2254] mccoy = ["Leonard McCoy", "Chief Medical Officer", 2266] ``` 首先,它会使较大的代码文件更难管理。因为 List 用索引管理成员,而人很难记住名字,年龄在哪个字段。 其次,如果员工各自列表中的元素数量不一致,就会产生错误。 类允许你创建用户定义的数据结构。类定义了称为方法的函数,这些方法确定了根据类创建的对象可以对其数据执行的行为和操作。 ## 类与实例 ### 定义一个类 **instance attributes** : 在 `.__init__()` 中创建的属性称为**实例属性**。实例属性的值是类的特定实例所特有的。 class attributes : **类属性**是对所有类实例具有相同值的属性。您可以通过在 `.__init__()` 之外为变量名赋值来定义类属性。 ```{code-block} python :emphasize-lines: 4 # dog.py class Dog: species = "Canis familiaris" def __init__(self, name, age): self.name = name self.age = age ``` ### 实例化 ```python >>> miles = Dog("Miles", 4) >>> buddy = Dog("Buddy", 9) ``` 可以用一个类创建很多个相似的实例,这是类最基本的优势。 ### 访问实例 ```python >>> miles.name 'Miles' >>> miles.age 4 >>> buddy.name 'Buddy' >>> buddy.age 9 >>> miles.species >>> buddy.species ``` 使用类来组织数据的最大优势之一,就是可以保证实例具有你所期望的属性。 ## Instance Methods ```{code-block} python :emphasize-lines: 10-17 # dog.py class Dog: species = "Canis familiaris" def __init__(self, name, age): self.name = name self.age = age # Instance method def description(self): return f"{self.name} is {self.age} years old" # Another instance method def speak(self, sound): return f"{self.name} says {sound}" ``` test: ```python >>> miles = Dog("Miles", 4) >>> miles.description() 'Miles is 4 years old' >>> miles.speak("Woof Woof") 'Miles says Woof Woof' >>> miles.speak("Bow Wow") 'Miles says Bow Wow' ``` ## `__str__()` 更加友好的打印对象: ```python >>> print(miles) #= <__main__.Dog object at 0x00aeff70> ``` 增加 ## `__str__` 方法, ```python # dog.py class Dog: # ... def __str__(self): return f"{self.name} is {self.age} years old" ``` 再次打印 Dog 对象: ```python >>> miles = Dog("Miles", 4) >>> print(miles) #= 'Miles is 4 years old' ``` ## 如何继承 ### over ridden ```python # inheritance.py class Parent: species = "Dog" hair_color = "brown" class Child(Parent): hair_color = "purple" # over ride ``` Child 拥有和 Parent 相同的 species, 但却拥有自己独特的 hair color。 ### extended ```python # inheritance.py class Parent: speaks = ["English"] class Child(Parent): def __init__(self): super().__init__() self.speaks.append("German") ``` ### 练习 创建一个新类JackRussellTerrier ,它继承于 Dog,当不给 speak 参数时,它发出 Arf 的声音, 但传入 sound 参数时,按 sound 提示发声。 ```python # dog.py class JackRussellTerrier(Dog): def speak(self, sound="Arf"): return f"{self.name} says {sound}" ``` ## Reference [When Should You Use .__repr__() vs .__str__() in Python? – Real Python](https://realpython.com/python-repr-vs-str/)