Python面向对象编程 从数据到对象
更新时间:2023-07-12数据类型与对象
在Python中,一切皆为对象。由于Python不需要提前声明变量的数据类型,而是根据赋值语句所带来的数据类型自动推导出变量的数据类型。Python中的数据类型非常多,对于整数字、浮点数、布尔型、序列、集合、字典等等数据类型,都有着相应的对象。
num = 42 # 整数数字
float_num = 3.14 # 浮点数数字
is_my_name_jack = False # 布尔型
my_list = [1, 2, 3, 4] # 列表
my_tuple = ('python', 'programming') # 元组
my_set = set([1, 2, 3, 4]) # 集合
my_dict = {'name': 'Jack', 'age': 26, 'hobbies': ['reading', 'coding']} # 字典
在Python中,每个对象都有自己的唯一标识符、类型和值。可以使用内置函数id()来获取对象的唯一标识符,type()来获取对象类型。
num1 = 42
num2 = 42
print(id(num1)) # 140723223301872
print(id(num2)) # 140723223301872,因为 num1 和 num2 引用的是同一个对象
print(type(my_dict)) # <class 'dict'>
类和实例
在Python中,使用class关键字定义一个类,表示一组具有相似属性和方法的对象的集合。类定义好之后,可以创建类实例,从而实例化对象。一个类定义了一个对象的模板,实例则基于模板构建具体对象。
class Person:
def __init__(self, name, age): # 初始化实例的一些属性
self.name = name
self.age = age
person1 = Person('John', 26)
print(person1.name) # John
print(person1.age) # 26
在上述示例中,我们定义了一个Person类,它有两个实例属性:name和age。__init__方法是一个构造函数,用于初始化类的实例,self是类实例,也就是对象自身。在创建Person实例时,name和age作为参数传递给构造函数,并被用于为实例属性赋值。
继承和多态
在面向对象编程中,继承是用于创建一个新类的机制,新类可以继承甚至修改旧类的一些特性。子类可以从父类那里继承所有属性和方法,并且可以根据需要添加自己的新特性或覆盖继承的方法。多态则允许一个变量引用一个类的实例及其子类的实例,这样可以保证程序在与对象交互时可以做到充分的灵活性。
class Animal: # 父类
def __init__(self, name):
self.name = name
def speak(self): # 父类的方法
raise NotImplementedError('子类中应该实现这个方法')
class Dog(Animal): # 子类继承父类
def speak(self): # 子类重写父类的方法
return 'Woof!'
class Cat(Animal):
def speak(self):
return 'Meow'
dog = Dog('Rufus')
cat = Cat('Linda')
print(dog.speak()) # Woof!
print(cat.speak()) # Meow
在上述示例中,我们定义了Animal类作为父类和Dog和Cat作为子类。父类定义了一个方法speak(),但是没有具体实现,而是扔了一个抽象异常未实现该方法。子类通过继承speak方法并重新实现它来定义自己不同的声音。
封装
Python允许您通过使用一个或多个下划线来指定访问模式来控制对象属性和方法的封装。下划线用于表示对象属性和方法的可见性。单个下划线前缀表示对象的方法或属性是受保护的,双下划线的前缀表示私有的。
class BankAccount:
def __init__(self, name, balance):
self._name = name # 受保护的属性
self.__balance = balance # 私有属性,外部直接访问会报错
def get_balance(self):
return self.__balance
account1 = BankAccount('Alice', 1000)
print(account1._name) # Alice
print(account1.get_balance()) # 1000
print(account1.__balance) # 报错
在上述示例中,我们定义了一个BankAccount类,它有两个属性:_name和__balance。_name是被保护的属性,因此外部可以访问,但每个开发人员都知道它是受保护的变量。__balance是私有属性,只能在类中访问,外部直接访问也会引发AttributeError异常。