Yunyuzuiluo

Python 百战 入门 7 面向对象编程基础

面向对象简介

Python完全采用了面向对象的思想,是真正面向对象的编程语言,完全支持面向对象的基本功能,例如:继承、多态、封装等。
Python中,一切皆对象。我们在前面学习的数据类型、函数等,都是对象。

对象类,属性和方法

class Student:
def init(self,name,score): #构造方法第一个参数必须为self
self.name = name #实例属性
self.score = score
def say_score(self): #实例方法
print("{0}的分数是{1}".format(self.name,self.score))
s1 = Student('张三',80) #s1是实例对象,自动调用__init__()方法
s1.say_score()

pass

pass 为空语句。就是表示什么都不做,只是作为一个占位符存在。当你写代码时,遇到暂时不知道往方法或者类中加入什么时,可以先用pass占位,后期再补上

init 构造方法和 new 方法

init_() 的要点如下:
1 名称固定,必须为: init()
2 第一个参数固定,必须为: self 。 self 指的就是刚刚创建好的实例对象
3 构造函数通常用来初始化实例对象的实例属性,如下代码就是初始化实例属性: name 和 score
def init(self,name,score):
self.name = name #实例属性
self.score = score
4 通过“类名(参数列表)”来调用构造函数。调用后,将创建好的对象返回给相应的变量。 比如: s1 = Student('张三', 80)
5 init() 方法:初始化创建好的对象,初始化指的是:“给实例属性赋值”
6 new() 方法: 用于创建对象,但我们一般无需重定义该方法
7 如果我们不定义 init 方法,系统会提供一个默认的 init 方法。如果我们定义了带参的 init 方法,系统不创建默认的 init 方法

实例属性和实例方法

class Student:
def init(self, name, score):
self.name = name # 学生姓名
self.score = score # 学生分数

def say_score(self):
    self.age = 18       # 动态添加年龄属性
    print("{0}的分数是{1}".format(self.name, self.score))

创建学生对象
s1 = Student("张三", 80) # 实例化学生对象s1
s1.say_score() # 调用方法打印分数并添加age属性
print(s1.age) # 打印动态添加的age属性
s1.salary = 3000 # 动态添加salary属性

s2 = Student("李四", 90) # 实例化学生对象s2
s2.say_score() # 调用方法打印分数并添加age属性
print(s2.age) # 打印动态添加的age属性

实例方法
def 方法名(self [, 形参列表]):
函数体

其他操作

dir(obj) 可以获得对象的所有属性、方法
obj.dict 对象的属性字典
pass 空语句
isinstance(对象,类型) 判断“对象”是不是“指定类型”

类方法 @classmethod

@classmethod
def 类方法名(cls [,形参列表]) :
方法体

@classmethod 必须位于方法上面一行
第一个 cls 必须有; cls 指的就是“类对象”本身
调用类方法格式: 类名.类方法名(参数列表) 。 参数列表中,不需要也不能给 cls 传值
类方法中访问实例属性和实例方法会导致错误
子类继承父类方法时,传入 cls 是子类对象,而非父类对象
class Student:
company = "SXT" #类属性
@classmethod
def printCompany(cls):
print(cls.company)
Student.printCompany()

静态方法 @staticmethod

@staticmethod
def 静态方法名([形参列表]) :
方法体

要点

@staticmethod 必须位于方法上面一行
调用静态方法格式: 类名.静态方法名(参数列表)
静态方法中访问实例属性和实例方法会导致错误
class Student:
company = "SXT" # 类属性
@staticmethod
def add(a, b): # 静态方法
print("{0}+{1}={2}".format(a,b,(a+b)))
return a+b
Student.add(20,30)

__del__方法 (析构函数)和垃圾回收机制

系统会自动提供 __del__方法 ,一般不需要自定义析构方法。

析构函数

class Person:
def del(self):
print("销毁对象:{0}".format(self))
p1 = Person()
p2 = Person()
del p2
print("程序结束")

call 方法和可调用对象

1 Python 中,凡是可以将 () 直接应用到自身并执行,都称为可调用对象。
2 可调用对象包括自定义的函数、Python 内置函数、以及本节所讲的实例对象。
3 定义了 call() 的对象,称为“可调用对象”,即该对象可以像函数一样被调用。
4 该方法使得实例对象可以像调用普通函数那样,以“对象名()”的形式使用。

def f1():
print("f1")
f1() #本质也是调用了__call__()方法
class Car:
def call(self, age,money):
print("call__方法")
print("车龄:{0},金额:{1}".format(age,money))
f2 = Car()
f2(3,200000) #像调用函数那样调用,本质也是调用了__call
()

Python中没有方法的重载。定义多个同名方法,只有最后一个有效

方法的动态性

测试方法的动态性

class Person:
def work(self):
print("努力上班!")
def play_game(self):
print("玩游戏")

def work2(s):
print("好好工作,努力上班!")

Person.play = play_game #为Person类新增play方法
Person.work = work2 #用work2替换原本work方法
p = Person()
p.play()
p.work()

私有属性和私有方法(实现封装)

通常我们约定,两个下划线开头的属性是私有的(private)。其他为公共的(public)。
类内部可以访问私有属性(方法)
类外部不能直接访问私有属性(方法)
类外部可以通过 _类名__私有属性(方法)名 ”访问私有属性(方法)

测试私有属性、私有方法

class Employee:
__company = "百战程序员" # 私有类属性,实际会被存储为_Employee__company

def __init__(self, name, age):
    self.name = name
    self.__age = age  # 私有实例属性,实际会被存储为_Employee__age

def say_company(self):
    """可以在类内部直接访问私有属性"""
    print("我的公司是:", Employee.__company)  # 类内部可以直接访问私有类属性
    print(self.name, "的年龄是:", self.__age)  # 类内部可以直接访问私有实例属性
    self.__work()  # 类内部可以直接调用私有方法

def __work(self):  
    """私有实例方法,实际会被存储为_Employee__work"""
    print("工作!好好工作,好好赚钱,娶个媳妇!")

测试代码

p1 = Employee("高淇", 32)
print(p1.name) # 可以正常访问公有属性

print(dir(p1)) # 查看对象的所有属性和方法,可以看到私有属性/方法被改名为_Employee__xxx的形式

p1.say_company() # 通过公有方法间接访问私有属性和方法

print(p1._Employee__age) # 可以通过改名后的形式直接访问私有属性(不推荐

@property 装饰器

测试@property装饰器

class Employee:
def init(self, name, salary):
self.name = name
self.__salary = salary # 私有属性,存储薪资

@property  # 将方法转换为属性(getter),相当于salary属性的getter方法
def salary(self):
    """获取薪资时自动调用,同时打印月薪和年薪"""
    print("月薪为{0},年薪为{1}".format(self.__salary, (12 * self.__salary)))
    return self.__salary

@salary.setter  # 设置属性的setter方法
def salary(self, salary):
    """设置薪资时进行验证"""
    if 0 < salary < 1000000:  # 薪资必须在0-1000000之间
        self.__salary = salary
    else:
        print("薪水录入错误!只能在0-1000000之间")

测试代码

emp1 = Employee("高淇", 100)
print(emp1.salary) # 访问salary属性时会调用@property修饰的salary方法
emp1.salary = -200 # 设置salary属性时会调用@salary.setter修饰的方法

属性和方法命名总结

_xxx :保护成员,不能用 from module import * 导入,只有类对象和子类对象能访问这些成员。
xxx :系统定义的特殊成员
__xxx : 类中的私有成员,只有类对象自己能访问,子类对象也不能访问。(但,在类外部可以通过 对象名. _类名__xxx 这种特殊方式访问。Python不存在严格意义的私有成员)

posted on 2025-04-21 17:55  刘晋宇  阅读(11)  评论(0)    收藏  举报

导航