day13-类和对象

13.1 编程思想

  • 1.编程思想:

1.面向过程编程 - 逻辑、算法
遇到问题考虑直接把逻辑思维转换成代码,解决问题
2.函数式编程 - 函数
遇到问题想到用函数解决。考虑是否有这种功能的函数。
3.面向对象编程 - 类和对象
遇到问题,就考虑是否有一个对象能帮我解决这个问题

  • 2.类和对象

1.定义
类:就是拥有相同属性和功能的对象的集合(类是抽象的)
对象:类的实例(对象是具体的)
2.从生活的角度考虑类的对象
如果‘人’是一个类,余婷是一个对象,骆老师也是一个对象。

13.2 类的声明

  • 1.类的声明
语法:
class 类名(父类列表):
    类的内容

说明:
class - 声明类的关键字
类名 - 标识符,不能是关键字;采用驼峰式命名,并且首字母大写;见名知义。
(父类列表) - 继承语法;可以省略,省略时相当于(objct)即基类(祖宗类)。
类的内容 - 主要包含属性和方法

补:驼峰式命名:名字由多个单词组成,通过单词首字母大写来区分不同的单词。
方法:python中声明在类中的函数叫方法。

  • 2.类的属性和方法

类中的属性 - 指的是在类中声明的变量;分为类的字段和对象属性
类中的方法 - 指的是在类中声明的函数;分为对象方法,类方法和静态方法。

# 声明了一个Person类
class Person:
    """人类"""
    num = 61      # 类的字段
    age = 61      # 对象属性
    name = 123

    # 方法
    def eat(self):
        print('%s在吃饭。' % Person.name)


# Person是类(类就是类型)
print(Person)              # 
  • 3.创建对象
类名()- 创建类对应的对象
xiao_ming = Person()
# 创建Person类的对象xiao_ming
print(xiao_ming)           # <__main__.Person object at 0x000001D82796B8D0>
xiao_ming.eat()            # 123在吃饭。
print(xiao_ming.name)      # 123

12.3 对象方法

  • 1.什么是对象方法
    直接声明在类中,并且自带一个叫self的参数的函数,就是对象方法。
  • 2.对象方法的调用 - 通过对象调用对象方法
    对象.对象方法()
  • 3.self(当前对象)
    通过对象调用对象方法时,对象方法中第一个参数self不用传参,系统会自动将当前对象传给self。哪个对象调用的self就指向谁。

注意:
当前类的对象能做的事情,self都能做。

# 创建一个Person类
class Person:
    """人类"""
    def __init__(self):
        self.name = ''
    # 声明了一个对象方法sleep
    def sleep(self):
        print('self', self)
        print('%s睡觉!' % self.name)
        self.run()                # 对象能做的,self都能做;当前对象

    def run(self):
        print('跑')


# 创建person对象p1
p1 = Person()
print('p1', p1)   # p1 <__main__.Person object at 0x0000017DADA7B4E0>
p1.sleep()        # self <__main__.Person object at 0x0000017DADA7B4E0>


p2 = Person()
p2.name = '小花'
p2.sleep()        # 小花睡觉!  跑

12.4 init方法和构造方法

  • 0.魔法方法:python类中,用__开头及结尾的方法,就是魔法方法,魔法方法不需要主动调用,都会自动调用。

  • 1._init_方法
    a.是对象方法,可用对象调用
    b.不需要自己调用,会被自动调用
    c.在创建对象后,专门用来对对象做初始化。

  • 2.构造方法
    概念:函数名和类名一样的函数,就是构造方法。用于创建对象。
    当我们创建类时,系统会自动创建这个类的构造方法,用来创建对象。
    当我们通过构造方法创建对象时,系统会自动调用init方法来对创建好的对象进行初始化。

注意:
当init方法中除了self以外如果需要别的参数,那么这些参数是通过构造方法传入的。
只要调用了构造方法,就会产生新的对象。想要对象,就要用构造方法。

class Person(object):
    def __init__(self, name, age=0):
        print('self', self)
        print('init方法', name)

"""
def Person(*args, **kwargs):
    在堆中开辟空间创建对象
    对象.__init__(*args, **kwargs)
    return 对象
"""
p0 = Person('abc', 10)
p1 = Person('abc', 10)
print('p1:', p1)

p2 = Person('123', age=20)
print('p2:', p2)
# p3 = Person()
p3 = p1


# 模拟构造方法和init方法
def __init__(a, b):
    print('自己实现', a, b)


def Person1(*args, **kwargs):
    # args = (10, 20)
    print('创建对象')
    __init__(*args, **kwargs)
    print('返回对象')


Person1(10, 20)
# 注意
tuple1 = (10, 20)
print(*tuple1)            # 10 20

13.5 对象属性

  • 1.什么是对象属性
    a.声明在_init_方法中
    b.self.属性名 = 值
    c.通过对象使用: 对象.属性
    d.不同的对象,属性可能不一样

语法:
self.变量名 = 值
说明:变量名就是属性名,这个变量就是对象属性

  • 2.什么样的属性应该声明成对象的属性
    如果属性值会因为对象不同而不一样,那这样的属性就应该声明成对象属性.反之声明成类的字段.
# 情况1:所有对象属性创建时都使用一个固定的默认值
class Person:
    def __init__(self):
        # 这里的name和age就是Person类的对象属性.
        self.name = ''
        self.age = 0


# 创建对象
p1 = Person()
# 使用对象属性
p1.name = 'ZH'
print(p1.name)      # ZH
print(p1.age)       # 0

p2 = Person()
p2.name = 'Z'
print(p1.name)      # ZH
print(p2.name)      # Z
print(p1.age)       # 0
print('='*88)


# 情况2:创建对象时,决定对象属性值
class Person:
    def __init__(self, name, age=1):
        # 这里的name和age就是Person类的对象属性.
        self.name = name
        self.age = age


# 创建对象
p1 = Person('ZH')
# 使用对象属性
# p1.name = 'ZH'
print(p1.name)      # ZH
print(p1.age)       # 1

p2 = Person('Z')
# p2.name = 'Z'
print(p1.name)      # ZH
print(p2.name)      # Z
print(p1.age)       # 1

# 修改对象属性值
p1.name = '流浪法师'
print(p1.name)         # '流浪法师'


# 练习,声明一个矩形类
"""
属性:长和宽
方法:求面积和求周长
"""


class Retangle:
    def __init__(self, length, width):
        self.length = length
        self.width = width

    # 一个对象方法,需不需要除了self以外的其他参数,看实现这个函数的功能需不需要除
    # 了属性以外的其他数据.
    def area(self):
        return self.width*self.length

    def perimeter(self):
        return (self.width+self.length)*2


j1 = Retangle(30, 20)
print(j1.area())                 # 600
print(j1.perimeter())                 # 100


# 练习:声明一个point类,拥有属性x,y坐标.拥有的功能是求一个点到另一个点的距离
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    # def distance(self, x1, y1):
    #     return ((self.x-x1)**2 + (self.y-y1)**2)**0.5
    def distance(self, other):
        return ((self.x-other.x)**2 + (self.y-other.y)**2)**0.5


p1 = Point(1, 2)
p2 = Point(4, 6)

# p1_p2 = p1.distance(p2.x, p2.y)
# print(p1_p2)                      # 5.0
print(p1.distance(p2))              # 5.0

13.6 对象属性的增删改查

class Dog:
    def __init__(self, name, color, type):
        self.name = name
        self.color = color
        self.type = type


dog1 = Dog('旺财', '黄色', '二哈')
  • 1.查(获取对象属性的值)

获取指定对象指定的属性
a.对象.属性名 - 属性不存在时会报错
b.getattr(对象,'属性名',默认值) - 当属性不存在时,如果设置了默认值,不会崩溃,会返回默认值.

print(dog1.name)                      # 旺财
# print(dog1.name1) # AttributeError: 'Dog' object has no attribute 'name1'

print(getattr(dog1, 'name'))              # 旺财
print(getattr(dog1, 'name1', '菜菜'))         # 菜菜
  • 2.增\改

a.对象.属性 = 值
b.setattr(对象,属性名,值)

注意:属性存在时,对应的功能是修改属性值.当属性不存在时,是添加属性.

dog1.name = '大黄'
print(dog1.name)          # 大黄;改
dog1.sex = '母'
print(dog1.sex)           # 母;增

setattr(dog1, 'name', 'hotdog')
print(dog1.name)                             # hotdog;改
setattr(dog1, 'name2', 'roudog')
print(dog1.name2)                            #  roudog;增
  • 3.删除

a.del 对象.属性
b.delattr(对象, 属性名)

del dog1.name
# print(dog1.name)     # AttributeError: 'Dog' object has no attribute 'name'

注意:对象属性的增删改查都是针对指定的那一个对象,不会影响其他对象

  • 4.slot魔法
__slots__是用来约束当前这个类有哪些对象属性
class Student:
    # Student类的对象只能有name age id sex这几个只能少,不能多
    __slots__ = ('name', 'age', 'id', 'sex')   # 限制类的属性

    def __init__(self, name,  age):
        self.name = name
        self.id = '001'
        self.age = age


stu1 = Student('小明', 18)
# stu1.neme = '666'       # 因为有slots魔法,所以不能添加
stu1.sex = '666'          # 可以添加,且不影响其他对象

13.6 类的字段和内置类属性

  • 1.类的字段
    a.声明在类中且在函数外的变量,叫做类的字段.
    b.类的字段需要通过类来使用:类.字段 - 不论是在类中还是类外,都需要。
    类的字段:不会因为对象不同而不一样的数据就声明为类的字段
class Person:
    # 声明了一个字段number
    number = 61

    def show_number(self):
        print('人类的数量:%d' % Person.number)


print(Person.number)           # 61
  • 2.内置类属性
    内置属性就是声明类的时候,类中已经声明好的属性(包含类的字段和对象属性),
class Dog:
    """说明文档:傻狗"""
    # 类的字段
    type = '犬科'

    # 声明对象属性
    def __init__(self, name, color, age):
        self.name = name
        self.color = color
        self.age = age

    # 对象方法
    def eat(self, food):
        print('%s在吃%s' % (self.name, food))

    # 类方法
    @classmethod
    def shout(cls):
        print('汪汪汪~')

    # 静态方法
    @staticmethod
    def bite():
        print('狗咬人!!')


dog1 = Dog('小黑', 3, '黑色')

a._name_
类._name_ - 获取类的名字(字符串)

print(Person.__name__)               # Person;获取类的名字

b._class_
对象._class_ - 获取对象对应的类(结果是一个类,类能做的它都可以做)

print(Person.__class__)        #   
print(dog1.__class__)          #  

dog1 = Dog('小黑', 3, '黑色')
dog2 = dog1.__class__('小黑', 3, '黑色')  # 可以创建对象
print(dog1.__class__.__name__)  # 有一个类的对象,可以获取到类的名字

c._dict_
(了解)类._dict_ - 获取当前类的所有字段及其对应的值
(重点)对象._dict_ - 将当前对象所有的对象属性及其值转换成字典,key是属性名,value是属性值.(数据本地化必须操作)

print(Dog.__dict__)     # 获取类的所有字段和其地址组成的字典
print(dog1.__dict__)     # {'name': '小黑', 'color': 3, 'age': '黑色'}

d._bases_
类._bases_ - 获取当前类的父类(以元组形式返回,元组中的元素就是类的父类名)

print(Dog.__bases__)      # (,)元组;python支持多继承,所以为元组

e._module_
类名._module_ - 获取当前类所在模块的模块名

print(Dog.__module__)  #  __main__

f._doc_
类._doc_ - 获取类的说明文档

print(Dog.__doc__)   # 说明文档:傻狗

你可能感兴趣的:(day13-类和对象)