面向对象编程初探

一、面向对象编程简介

'''
面向对象编程
    核心是对象二字,对象的特征与技能的结合体
    基于该思想编写的程序就好比在创造一个世界(世界是由一个个的对象组成的),程序员就是这个世界的上帝,对于上帝来说任何存在的事物都是对象,任何不存在的事物也可以创造出来,使一种上帝式的思维方式

优点:
    可扩展性强
缺点:编程的复杂度高


类:
    如果说对象是特征与技能的结合体,类则是一系列对象相似的特征与技能的结合
    在现实世界中,一定先有一个具体的对象,然后随着人类文明的发展由人类站在不同角度总结出类
    注意:
        类是抽象的概念,而对象才是具体存在的事物
        站在不同角度,可以总结出不同的类
    在程序中,一定要先定义类,后调用类产生对象
''' 

二、通过与面向过程编程的流程对比,引入类的定义

# 面向过程和面向对象流程上的不同之处
# 假设要处理学生的成绩表,为了表示一个学生的成绩,面向过程的程序可以用一个dict表示:
stinfo = {
    'name': 'fred',
    'score': 80
}


# 处理成绩可以用函数实现,比如修改成绩

def score(stinfo):
    stinfo['score'] = 90
    print(stinfo)


# score(stinfo)

# 如果采用面向对象的程序设计思想,首先思考的不是程序的执行流程,而是student这种数据类型应该被视为一个对象,这个对象拥有namne和score这两个属性,如果要修改学生成绩,首先必须创建出这个学生对应的对象,然后给对象发一个修改的消息

# 定义类:
class Student(object):
    addr='shanghai'
    def __init__(self, name, score):
        self.name = name
        self.score = score

    def modified_score(self):
        self.score = 90
        print(self)

'''
定义类时会立刻触发类体代码的运行,会产生一个类的名称空间,将类体代码运行过程中产生的名字都存到类的名称空间中
ps:定义类的本质就是创造出一个名称空间,用来存放名字的,即类就相当于一个容器
'''
面向过程与面向对象的流程对比
'''
__init__方法:
    为对象初始化自己独有的特征
强调:
  1、该方法内可以有任意的python代码
  2、一定不能有返回值
    
'''
__init__方法
class Student(object):
    addr='shanghai'
    def __init__(self, name, score):
        self.name = name
        self.score = score

    def modified_score(self):
        self.score = 90
        print(self)


print(Student.__dict__)   # 查看类的名称空间
'''
{'__module__': '__main__', 'addr': 'shanghai', '__init__': <function Student.__init__ at 0x03D4B660>, 'modified_score': <function Student.modified_score at 0x059A45D0>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}
'''

# 查看
print(Student.addr)  # 数据属性
print(Student.modified_score)  # 函数属性

# 增加
Student.phone = 180000013
print(Student.phone)

# 修改
Student.addr = 'beijing'
print(Student.addr)

# 删除
del Student.phone
print(Student.phone)
类/对象的增删改差(直接操作对象本身)
'''
反射:是通过字符串来操作类或者对象的属性
此方法类和对象都可以使用
    getattr()
    setattr()
    delattr()
    hasattr
'''


class Student(object):
    addr='shanghai'
    def __init__(self, name, score):
        self.name = name
        self.score = score

    def modified_score(self):
        self.score = 90
        print(self)

#### getattr()    三个参数,(类/对象,字符串形式的属性名称,default) 查看属性的值

stu1 = Student('fred', 80)

print(getattr(Student, 'addr'))     # 等同于Student.__dict__['addr']
# print(getattr(Student,'phone'))
print(getattr(Student, 'phone', None))
print(getattr(stu1, 'name'))

'''
shanghai
AttributeError: type object 'Student' has no attribute 'phone'   # 查询一个不存在的属性,则报错
None    # getattr还有第三个参数,可以加默认值,即属性存在,则返回属性的值,属性不存在,则返回默认值,不至于让程序报错
fred    getattr同样适用于对象
'''

### setattr()   三个参数,(类/对象,字符串形式的属性名,'属性的新值')  有则改值,无则新增
setattr(Student,'addr','ShangHai')    # 等同于Student.addr='ShangHai'
print(getattr(Student,'addr'))

setattr(stu1,'name','Fred')
print(getattr(stu1,'name'))
setattr(stu1,'phone','187')

print(getattr(stu1,'phone'))
'''
ShangHai     # 修改类属性的值,注意一旦修改了类的属性值,那么调用此类的所有对象都会被改
Fred         # setattr()同样适用对象
187          # phone属性添加成功
'''


# delattr()   删除属性   两个参数(对象/类,'字符串形式的属性名字')
delattr(stu1,'phone')
# print(stu1.phone)

'''
AttributeError: 'Student' object has no attribute 'phone'   # 删除成功
'''

# havesttr() 判断属性是否存在,存在True  不存在False

print(hasattr(stu1,'phone'))  

'''
False
'''
类/对象的增删改查(反射)

三、使用类

'''
类的两种用途:
    1.当做一个容器(名称空间)
    print(Student.__dict__)
    {'__module__': '__main__', 'addr': 'shanghai', '__init__': <function Student.__init__ at 0x04A45618>, 'modified_score': <function Student.modified_score at 0x04A455D0>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}

    2、调用类产生或者实例化出对象
    stu1 = Student('fred', 80)
    
'''

class Student(object):
    addr='shanghai'
    def __init__(self, name, score):
        self.name = name
        self.score = score

    def modified_score(self):
        self.score = 90
        print(self)

# 调用类产生stu1对象(调用类的过程称之为实例化,得到的结果是一个类的实例/对象)
'''
调用类发生了两件事:
    1、会产生一个空对象
    2、会触发类中__init__函数的运行,将空对象连同括号内的参数一同传入
'''

stu1 = Student('fred', 80)   # 调用Studen类产生s1的空对象,触发Studen.__init__('fred',80)绑定方法,stu1调用Stundent.__init方法,那么stu1就会当做第一个参数自动传入

四、属性查找及对象的绑定方法

class Student(object):
    addr = 'shanghai'

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

    def modified_score(self):
        self.score = 90
        print(self)

    def print_score(self):
        print('this is your score')


'''
属性查找:
    对象的本质就是一个容器,即对象名称空间
    类的本质也是一个容器,即类的名称空间 
    属性查找的顺序: 对象的名称空间———类的名称空间
    如果类的名称空间没找到则报错 'Student' object has no attribute 'phone'  
'''
stu1 = Student('fred', 80)
stu2 = Student('Fred_Li',90)
print(id(stu1.addr))
print(id(stu2.addr))

print(stu1.addr)

'''
41736696
41736696
结论:类的数据属性是共享给所有对象
'''

'''
类中定义的函数是类的函数属性,类可以使用,但类使用时就是一个普通的函数,必须遵守函数的规则
但是,类中定义的函数其实是给对象用的,而且是绑定给对象用,称为绑定方法

绑定方法的特殊之处:
    绑定给谁就应该由谁来调用,谁来调用就会将谁当做第一个参数自动传入
'''

Student.print_score('xxx')    # 类使用类中的函数,必须要给self传值Student.print_score()    # 类使用类中的函数,必须要给self传值
'''
print_score() missing 1 required positional argument: 'self'
'''
stu3=Student('Fred',90)     # __init__(self, name, score)  stu3当第一个参数自动传入   Fred和90分别传给name和score

print(stu3.__init__)        # <bound method Student.__init__ of <__main__.Student object at 0x04DB1B10>> __init__的绑定方法
print(stu1.__dict__)        # 对象独有的特征
'''
类与类型,在Python3中统一了类与类型的概念,类就是类型
'''

class Student(object):
    addr='shanghai'
    def __init__(self, name, score):
        self.name = name
        self.score = score

    def modified_score(self):
        self.score = 90
        print(self)

print(type(Student),Student)
print(type(list),list)


'''
<class 'type'> <class '__main__.Student'>
<class 'type'> <class 'list'>
即:list就是Python内置的类   而Student可以立即为自定义的类 
'''

stu1=Student('fred',80)
l1=list(['fred',20])

print(l1.append)
print(stu1.modified_score)

'''
<built-in method append of list object at 0x049F7698>
<bound method Student.modified_score of <__main__.Student object at 0x049F1470>>

即: 
    append是l1调用了list类的绑定方法
    modified是stu1调用了Studentl类的绑定方法

第一个参数是对象自动传入的
'''
Python3中的类与类型
原文地址:https://www.cnblogs.com/lichunke/p/9448708.html