面向对象基础,类与对象,属性查找顺序,绑定方法

面向过程编程
    关键在于过程
    过程指的是,先干啥 在干啥 最后在干啥  是完成,某个任务的具体步骤
    注意:面向过程与函数编程时完全不同的
    优点:将复杂的问题拆分为若个简单问题,然后按照顺序一步一步完成
    从使得问题,简单化,流程化
    缺点:由于代码严格按照顺序来编写 导致扩展性极差
    类似一条流水线  一旦设计完成就只能完成某种固定的任务
    后期如果需要修改需求  则需要完成重新设计

    使用场景:对扩展性要求较低的应用程序
        例如:操作系统内核,运维编写的shell脚本程序等

面向对象编程
    是一种编程思想
    关键在于对象,对象是一系列特征和行为的结合体
    使用面向对象来编写程序时 需要将程序员看作是上帝,不是去思考具体的实现步骤
    重点关注的是什么样的对象可以完成这个事情
        面向过程想的是:怎么做
        面向对象想的是:谁来做

    优点:扩展性高,修改单独某一个对象,不会影响到其他对象
          复用性,灵活性,降低耦合度

    缺点:1.相对于面向过程而言,编程的复杂度提高了
          衡量一款软件的指标有很多,比如  扩展性,可用性,易用性,成本等等
          2.无法准确预知执行结果

    使用场景:对扩展性要求较高的应用程序,比如qq  一年四季都在加功能(面向用户应用程序扩展性要求都高)
        例如:qq微信  淘宝,支付宝。。。。

类:
    类型  类别  分类
    类是一堆对象 相似的特征和相似的行为的结合体,是一种抽象概念

    类和对象的关系:
    生活中 现有对象,再有类
    程序中 先有类 在由类产生对象

    可以把类当作是一个对象的模板,或者是对象的工厂

 

使用面向对象编程时 第一步要做的是分析需求中涉及到的对象和类
注意:站在不同的角度分析得到的类是完全不同的

1.定义一个类时 就会产生一个名称空间,
2.并且执行类中代码将产生的名称存储到名称空间中
3.将类名称 绑定到名称空间

类名的命名规范是 大驼峰 所有单词首字母 大写

class Student:
    school = "oldboy"

    def study(self):
        print("is studying")

    def sleep(self):
        print("is sleeping")
    print("==============")

print(Student.school)
print(Student.study)
Student.study(1)

产生对象:

class Student:
    # 类中只存储相同的特征和行为
    # 在面向对象中 特征和行为统称为属性
    school = "oldboy"

    def study(self):
        print("is studying")

    def sleep(self):
        print("is sleeping")

# 调用类产生一个对象
# stu1 = Student()
# print(stu1)
#
# print(stu1.school)
# print(stu1.study)
#
stu2 = Student()
print(stu2.school)
# 默认情况下 对象的名称空间是空的  通过点可以增加属性
print(Student.__dict__)
print(stu2.__dict__)
stu2.name = "Alex"
stu2.sex = "woman"
stu2.number = "007"
print(stu2.__dict__)
print(stu2.name)

stu3 = Student()
stu3.name = "Blex"
stu3.sex = "man"
stu3.number = "008"

创建对象后可以通过点来增加属性  但是不推荐这么做,而且代码冗余

# 颜色  性别  年龄
class Dog():
    dog_type = "中华唐犬"
    # 在实例化对象的时候会自动执行该函数 并且自动把刚创建出来的对象传进来 作为第一个参数
    def __init__(self,a,b,c):
        print(" init run")
        self.color = a
        self.sex = b
        self.age = c
        print(self)

    # 谁调用方法 self就是谁
    def watch_door(self):
        print(self.name,"is 看门")

# dog1 = Dog() # == Dog(dog1)
# print(dog1.color)

# dog2 = Dog("blue","male",3) # == Dog(dog1)
# print(dog2.color)
# # Dog.watch_door()
#
# dog3 = Dog("yellow","male",2) # == Dog(dog1)
# print(dog3.color)

# dog3.watch_door()
# print(dog3)

# 不推荐在对象产生后为其增加属性
# dog4 = Dog("red","male",2) # == Dog(dog1)
# dog4.watch_door()
# dog4.name = "大红"

对象既可以访问自己名称空间中的内容 也可以访问类中
如果出现相同的优先访问自己的
顺序: 对象 -> 类

class Pig():
    pig_type = "野猪"

    def __init__(self,age):
        self.age = age

    def eat(self):
        print("野猪吃野菜")

# pig1 = Pig(2)
# print(pig1.age)
# print(pig1.__dict__)
#
# pig1.pig_type = "家猪"
# print(pig1.__dict__)
# print(pig1.pig_type)

pig2 = Pig(2)
pig3 = Pig(1)

# pig2.price = 10
# print(pig2.price)

# print(pig3.price) # pig3不存在这个属性 对象间名称空间是相互独立的

# pig2.pig_type = "家猪"
#
# print(pig2.pig_type)
# print(pig3.pig_type)

# 类中的属性被所用对象共享
print(id(pig2.pig_type))
print(id(pig3.pig_type))

绑定方法
    方法指得就是函数
    其实就是把函数和对象进行了绑定
    对象本质就是一个数据容器 里面存储多个属性
    函数是用于处理数据的代码段

    对象精髓就是 将数据和处理数据的函数绑定在一起

    绑定方法的好处是  只要拿到了对象 就同时拿到了要处理的数据 以及处理数据的方法

    通常情况下 类中的大多数函数都是绑定给对象的方法  因为这些函数需要使用到对象中包含的数据

class Person():
    def __init__(self,name,sex,age):
        self.name = name
        self.age = age
        self.sex = sex
    # 默认情况下  类中的所有函数都是绑定方法  都是绑定给对象的
    def say_hi(self):
        print("hello i am %s" % self.name)

# p1 = Person("Tiger","man",18)
#
# print(p1.say_hi)
#
# def working(obj):
#     print(obj.say_hi())
#
# working(p1)
# 绑定方法 本质就是函数  那么与普通函数的区别是什么?
p2 = Person("王大锤","man",20)
p2.say_hi()

# 当使用对象来调用绑定方法时 会自动将对象作为第一个参数传给绑定方法
p2.say_hi()
# 当使用类来调用绑定方法时 需要手动传入第一个参数
Person.say_hi(p2)

默认情况下 类中的方法都是绑定给对象的

    类中的方法 分为两类
    1.绑定方法
        1.1对象的绑定方法 (默认)
        1.2类的绑定方法
            语法:使用@classmethod装饰器
            使用场景:当一个方法的执行逻辑中需要访问类中的属性时,就应该作为类的绑定方法
    2.非绑定方法
    语法: 给方法加上 staticmethod装饰器
    使用场景 当一个方法的执行逻辑中不需要访问对象中也不需要访问类中的数据时
    就应该定义为非绑定方法

# 场景总结:
# 如果这个方法需要访问对象中的数据 那就作为 对象绑定方法(默认)
# 如果这个方法需要访问类中的数据 那就作为 类绑定方法(@classmethod)
# 如果这个方法不需要访问类和对象中的数据 那就作为 非绑定方法(@staticmethod)

class Person:
    color = "yellow"

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

    def say_hi(self):
        print("my name is %s" % self.name)

    输出person的肤色
    @staticmethod
    def show_color():
        print(Person.color)

    @classmethod
    def show_color(cls):
        # print(Person.color)
        print(cls)
        print(cls.color)

    def show_color2(self):
        print(Person.color)
        print(self)
        print(self.color)

    @staticmethod
    def show_color3(a):
        print("show_color3 run",a)

Person.show_color()
p1 = Person("xx")

p1.show_color()
Person.show_color()  # 类方法在使用类调用时会自动传入这个类本身作为第一个参数
Person.show_color2() # 对象绑定方法在使用类调用时不会自动传参

p2 = Person("xx")
p2.show_color() # 对象调用类的绑定方法时也会自动传入类本身
p2.show_color2() # 对象调用对象的绑定方法时也会自动传入对象本身

非绑定方法 类和对象都可以直接调用   但是无论谁调用都不会有自动传值的效果
Person.show_color3()
p2.show_color3()

你可能感兴趣的:(面向对象基础,类与对象,属性查找顺序,绑定方法)