python面向对象基础

心不动则不痛 提交于 2019-11-30 13:16:50

一、面向过程VS面向对象

面向过程

  • 优点:极大的降低了写代码的复杂度,只需要顺着执行的步骤,堆叠代码即可。
  • 缺点:一套流水线或者流程下来是用来解决一个问题,代码牵一发而动全身。

面向对象

  • 优点:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。
  • 缺点:可控性差。

二、初识类和对象

1、类

  • 类的声明
'''
class 类名:
    '类的说明文档'
    类体
'''

# 创建一个类
class Student:  # 类名一般开头大写
    class_num = 'robot3'
    
    def stu_speak(self):
        print('student is speaking!')
  • 类的两种作用:属性引用和实例化
  1. 属性引用(类名.属性)
class Student:
    class_num = 'robot3'

    def stu_speak(self):
        print('student is speaking!')


print(Student.class_num)  # 查看学生的班级属性
print(Student.stu_speak)  # 引用学生的说话方法

# output
robot3
<function Student.stu_speak at 0x000002934C4E87B8>
  1. 实例化(类名加括号就是实例化,会自动触发__init__函数的运行,可以用它来为每个实例定制自己的特性)
class Student:
    class_num = 'robot3'

    def __init__(self, name):  # 每个学生都有自己的姓名
        self.name = name

    def stu_speak(self):
        print('student is speaking!')


# 实例化一个对象,这个对象的名字属性是‘jacky’
# 类名()就等于在执行Student.__init__(), 这个对象类似一个字典,存着属于这个学生本身的一些属性和方法。
jacky = Student('jacky')

#查看属性和调用方法
print(jacky.name)  # 对象名.属性
print(jacky.stu_speak)  # 对象名.方法名()
  • 类属性的补充
一:我们定义的类的属性到底存到哪里了?有两种方式查看
dir(类名):查出的是一个名字列表
类名.__dict__:查出的是一个字典,key为属性名,value为属性值

二:特殊的类属性
类名.__name__# 类的名字(字符串)
类名.__doc__# 类的文档字符串
类名.__base__# 类的第一个父类(在讲继承时会讲)
类名.__bases__# 类所有父类构成的元组(在讲继承时会讲)
类名.__dict__# 类的字典属性
类名.__module__# 类定义所在的模块
类名.__class__# 实例对应的类(仅新式类中)

2、对象
对象是关于类而实际存在的一个例子,即实例

对象/实例 只有一种功能:属性引用(方法也是属性,只不过是类似函数的属性,我们也管它叫动态属性,调用时后面加上括号)

固定模式

class 类名:
    def __init__(self, 参数1, 参数2):
        self.对象的属性1 = 参数1
        self.对象的属性2 = 参数2
        
    def 方法名1(self):
        pass
    
    def 方法名2(self):
        pass
    
对象名 = 类名(1, 2)  # 实例化,参数不需要传self

# 属性引用
对象名.对象的属性1
对象名.方法名()

三、类命名空间与对象、实例的命名空间

创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性
类有两种属性:静态属性和动态属性

  • 静态属性是直接在类中定义的变量
  • 动态属性是定义在类中的方法

类的数据属性共享给所有对象

print(id(jacky.class_num))  # 3025487647384
print(id(Student.class_num))  # 3025487647384

类的动态属性是绑定到所有对象的

print(jacky.stu_speak)
print(Student.stu_speak)

# output
<bound method Student.stu_speak of <__main__.Student object at 0x000001FE7FEC0898>>
<function Student.stu_speak at 0x000001FE00EC87B8>

对于不可变数据类型,类变量最好用类操作

class Course:
    language = 'Chinese'

    def __init__(self, teacher, course_name):
        self.teacher = teacher
        self.name = course_name


python = Course('weige', 'python')


# 对象对类静态属性的修改只有在本对象才有效
python.language = 'English'
print(python.language)  # English
print(Course.language)  # Chinese

对于可变数据类型,变量的修改是共享的,重新赋值是独立的

class Course:
    language = ['Chinese']

    def __init__(self, teacher, course_name):
        self.teacher = teacher
        self.name = course_name


python = Course('weige', 'python')


# 对象对类静态属性的修改同步到了类上
python.language[0] = 'English'
print(python.language)  # ['English']
print(Course.language)  # ['English']

# 对象对类静态属性的重新赋值只对自身起效果
python.language = 'a language you don\'t know'
print(python.language)  # a language you don't know
print(Course.language)  # ['English']

怎么理解?类的数据属性共享给所有对象,但是当数据属性是可变数据类型时,比如列表,列表的地址是共享的,列表内部的修改并不会改变列表的地址,所以变量的修改是共享的,对象对类静态属性的修改将同步到类。

print(id(python.language))  # 2644085527496
print(id(Course.language))  # 2644085527496

# 列表的地址没有改变
python.language[0] = 'English'

print(id(python.language))  # 2644085527496
print(id(Course.language))  # 2644085527496

对象对数据属性重新赋值时,将产生一个新的地址,这种赋值效果只对自身有效。

print(id(python.language))  # 2642364355528
print(id(Course.language))  # 2642364355528

python.language = 'English'

print(id(python.language))  # 2642347558984  变成一个新的地址
print(id(Course.language))  # 2642364355528

四、组合

组合:在一个类中以另外一个类的对象作为数据属性,称为类的组合

class Birthday:
    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day


class Course:
    language = 'Chinese'

    def __init__(self, course_name):
        self.name = course_name


class Teacher:
    def __init__(self, name, age, sex, birthday):
        self.name = name
        self.age = age
        self.sex = sex
        self.birthday = birthday
        # 此处传入一个Course对象作为Teacher类的一个属性
        self.course = Course('python')


b = Birthday(2019, 9, 22)
# 此处传入一个Birthday对象赋值给Teacher类 用以实例化一个Teacher对象
hh_teacher = Teacher('jack', 0, 'boy', b)
print(hh_teacher.birthday.year)
print(hh_teacher.course.name)

# output
2019
python
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!