Python之面向对象

面向对象

在python中,万物皆对象
类(类型)和对象(这个类型中的一个具体的数据)

一、类和对象

1、类

是一类事物的抽象概念(模型),不是真实存在的,描绘了该类事物共同的特征和行为
例如:船模型、车模型、飞机模型

2、实例对象

某个事物的具体个体,是该类事物的具体表现,它是真实存在的
例如:“辽宁号”是一艘具体的船,“泰坦尼克号”也是一艘具体的船

也可以理解为,类是图纸上的模型,对象是具体造出来的东西
猴类:齐天大圣,六耳猕猴 是对象
水果类:苹果,香蕉,梨是对象

3、类的定义

class 类名:
该类事物共有的特征和行为(属性和方法)
类名规范:大驼峰的形式命名(每个单词第一个字母大写)
特征:属性
行为:方法

4、属性(共有特征)

类属性:
直接定义在类里面的变量(该类事物共有的特征,所有对象特征值都是一样的)
获取类属性:对象.属性名,类.属性名
对象属性(实例属性):
对象自己的一些属性(和类里面的其他对象属性值有可能是不一样的)
实例属性的定义:对象.属性名=属性值
获取实例属性:只能通过对象来获取,对象.属性名

5、样例

class GirlFriend:
    # 女朋友类
    # 类属性
    gender = '女'

# 通过类创建一个对象
obj = GirlFriend()
# 实例属性
obj.name = '小白'
obj.height = '160cm'
obj.weight = '44kg'

# 获取属性值
# 类属性:可以通过类取获取,也可以通过对象取获取
print(obj.gender) # 通过对象获取
# 运行结果:女
print(GirlFriend.gender) # 通过类获取
# 运行结果:女
# 实例属性:只能通过对象取获取
print(obj.name)
# 运行结果:小白
# 通过类获取的话会报错,如下
# print(GirlFriend.name) # 这个.的时候也不会展示
# 运行结果:AttributeError: type object 'GirlFriend' has no attribute 'name'

6、初始化方法__init__

__init__方法:初始化方法(初始化对象属性)
背景:
如果想在定义一个对象,再写一遍就比较麻烦。可以通过初始化方法来实现。

'''
想再定义一个对象,就得上面的再来一遍。可以定义一个初始化方法
obj2 = GirlFriend()
# 实例属性
obj2.name = '小白'
obj2.height = '160cm'
obj2.weight = '44kg'
'''

方法:定义在类里面的函数
init方法定义了几个参数,创建对象的时候就要传几个参数(self除外)
self:代表对象自己,哪个对象调用方法,就代表哪个对象

class GirlFriend:
    # 女朋友类
    # 类属性
    gender = '女'

    # 初始化方法
    # __init__方法:初始化方法(初始化对象属性)
    def __init__(self, name, height, weight):
        # 每个对象的属性不一样,不能写死,可以通过变量脸实现。方法的本质是函数,可以传参
        self.name = name
        self.height = height
        self.weight = weight

object=GirlFriend('小白',160,44)
print(object.name)
# 运行结果:小白
'''
# 不传参数创建对象是不可以的哦,会报错
obj1 = GirlFriend()
# 运行结果:TypeError: __init__() missing 3 required positional arguments: 'name', 'height', and 'weight'
'''

7、类方法和实例方法

方法:定义在类里面的函数
方法的调用:对象.方法名()

1)__init__方法

在创建对象的时候自动调用

2)实例(对象)方法

实例(对象)方法的定义:直接定义在类里面的函数
方法的第一个参数是self,self代表的是对象自己
实例(对象)方法的调用:对象.方法名(注意:类不能调用对象方法)

class GirlFriend:
    # 女朋友类
    # 类属性
    gender = '女'

    # 初始化方法
    # __init__方法:初始化方法(初始化对象属性)
    def __init__(self, name, height, weight):
        # 每个对象的属性不一样,不能写死,可以通过变量脸实现。方法的本质是函数,可以传参
        self.name = name
        self.height = height
        self.weight = weight
    # 实例方法(对象方法)
    def skill1(self):
        print('败家')

    @classmethod   #通过classmethod装饰器,声明一个类方法
    def cls_func(cls):
        print('这是一个类方法')

object1=GirlFriend('小白',160,44)
object2=GirlFriend('小月',162,50)

object1.skill1()
GirlFriend.skill1()

运行结果:
败家
TypeError: skill1() missing 1 required positional argument: ‘self’

适用场景:

方法中会用到实例的属性或者方法,适合定义为实例方法

3)类方法

类方法的定义:前面加个@classmethod,通过classmethod装饰器来声明一个类方法
类方法的第一个参数,通常定义为cls,cls代表的是类本身
类方法的调用:类.方法名,对象.方法名
类方法里面既不会使用到对象属性,也不会调用对象的方法

class GirlFriend:
    # 女朋友类
    # 类属性
    gender = '女'

    # 初始化方法
    # __init__方法:初始化方法(初始化对象属性)
    def __init__(self, name, height, weight):
        # 每个对象的属性不一样,不能写死,可以通过变量脸实现。方法的本质是函数,可以传参
        self.name = name
        self.height = height
        self.weight = weight
    # 实例方法(对象方法)
    def skill1(self):
        print('败家')

    @classmethod   #通过classmethod装饰器,声明一个类方法
    def cls_func(cls):
        print('这是一个类方法')

object1=GirlFriend('小白',160,44)
object2=GirlFriend('小月',162,50)

# object1.skill1()
object1.cls_func()
GirlFriend.cls_func()

运行结果:
这是一个类方法
这是一个类方法
适用场景:方法中不会用到实例的属性或者方法;有可能会用到类的属性或者

8.静态方法

定义:使用装饰器@staticmethod,参数随意,没有cls和self参数,方法体中不能使用类活实例的任何属性和方法
调用:实例对象和类对象均可调用
应用场景:存放逻辑代码,内部不需要引用类属性和实例属性

9.私有属性

1.类属性
共有属性:不管在类里面还是类外面都可以访问
私有属性:两个下划线开头的属性叫私有属性,只能在类里面访问,类外貌是用不了

lass MyClass:
    attr = 100	# 公有属性
    _attr = 200  # 在外部可以访问,但是不要在内外部使用
    __attr2 = 999  # 强制拒绝外部访问
print(MyClass.attr)
print(MyClass._attr)
print(MyClass.__attr)

二、继承

2.1类的定义形式分两种

1、class 类名:
Python2中称为经典类,Python3中默认继承object
class MyTest:
pass
Python2中称为新式类
2.class MyTest(object):
pass
在python3中上面两种定义方式没有任何区别,都是继承object这个父类

2.2基类object

1、python中所有类的祖宗(所有的类都继承于它)
2、所有类默认继承于object

class MyTest():
    pass

class MyTest2(object):
    pass

m1=MyTest()
M2=MyTest2()

print(m1.__dict__)
print(M2.__dict__)

2.3 什么是继承,继承有什么用

  • 子类通过继承能够拥有父类的属性和方法
  • 注意:__开头的私有属性和方法不能继承
  • 被继承的的类叫父类(基类),继承的类叫子类
  • 作用:子类通过继承能够拥有父类的属性和方法,可以提高开发的效率和代码的复用率
class BaseClass:
    money = 1000000

    def func(self):
        print("赚钱方法:日赚100万")


class MyClass(BaseClass):
    def func2(self):
        print("败家方法:日花101万")


a = MyClass()
print(a.money)
a.func()
a.func2()

运行结果:
1000000
赚钱方法:日赚100万
败家方法:日花101万

class BaseClass:
    money = 1000000

    def func(self):
        print("赚钱方法:日赚100万")


class MyClassV1(BaseClass):
    def func2(self):
        print("败家方法:日花101万")


class MyClassV2(MyClassV1):
    def func3(self):
        print("破产方法:日花1000万")


a = MyClassV2()
print(a.money)
a.func()
a.func2()
a.func3()

运行结果:
1000000
赚钱方法:日赚100万
败家方法:日花101万
破产方法:日花1000万
==》四层继承
object->BaseClass->MyClassV1->MyClassV2

2.4 继承的定义

语法:class 类名 (父类名):
小案例
需求V1:实现一个初始版的手机类(大哥大)
只能打电话
需求V2:实现一个功能手机类
打电话,听音乐
需求V3:实现一个智能手机类
打电话,听音乐,玩游戏
1、不使用继承模式

class BasePhone:

    def call_phone(self):
        print("这是个打电话的功能")
class PhoneV1(object):
    def call_phone(self):
        print("这是个打电话的功能")
    def music(self):
        print("这是个听音乐的功能")
class PhoneV2(object):
    def call_phone(self):
        print("这是个视频通话的功能")
    def music(self):
        print("这是个听音乐的功能")
    def game(self):
        print("这是个玩游戏的功能")

2、使用继承模式(提高代码的重用率,节省代码)

class BasePhone:

    def call_phone(self):
        print("这是个打电话的功能")


class PhoneV1(BasePhone):
    def music(self):
        print("这是个听音乐的功能")


class PhoneV2(PhoneV1):
    def call_phone(self):
        print("这是个视频通话的功能")

    def game(self):
        print("这是个玩游戏的功能")

2.5重写父类
重写父类方法:在子类中定义一个和父类同名的方法,这个方法叫做重写父类

class BasePhone:

    def call_phone(self):
        print("这是个打电话的功能")


class PhoneV1(BasePhone):
    def music(self):
        print("这是个听音乐的功能")


class PhoneV2(PhoneV1):
    def call_phone(self):
        print("这是个视频通话的功能")

    def game(self):
        print("这是个玩游戏的功能")

phone=PhoneV2()
phone.call_phone()

在子类中调用父类同名的方法:
方式一:父类名.方法名(self)
方式二:super().方法名()
推荐使用方式二(超类)

class BasePhone:

    def call_phone(self):
        print("这是个打电话的功能")


class PhoneV1(BasePhone):
    def music(self):
        print("这是个听音乐的功能")


class PhoneV2(PhoneV1):
    def call_phone(self):
        print("这是个视频通话的功能")
        print('视频电话5分钟后切换语音通话')
        # 调用父类的同名方法
        # BasePhone.call_phone(self)
        super().call_phone()

    def game(self):
        print("这是个玩游戏的功能")

phone=PhoneV2()
phone.call_phone()

运行结果:
这是个视频通话的功能
视频电话5分钟后切换语音通话
这是个打电话的功能
**注意点:**父类是不能使用子类的方法和属性的
**应用场景:**父类中原有的方法不能满足当前的需求,需要对父类中的方法进行扩展
开放封闭原则:
1、已经实现的功能不要进行修改(对修改是封闭的)
2、对功能的扩展是开放的

2.5 动态属性设置

对象.__dict__属性:获取对象的所有属性,以字典的形式返回
动态属性设置:
内置函数:setattr(参数1,参数2,参数3)
参数1:对象
参数2:给这个对象设置属性名(字符串类型)
参数3:属性值

# 需求:字典中的key作为属性名,value作为属性值
data = {'case_id':1, 'title':'用例1','url' :'www.baidu.com', 'data' :'001'}

class Cases:
    pass

case=Cases()
for k,v in data.items():
    setattr(case,k,v)

print(case.__dict__)

setattr(ojb,属性名,属性值)

1)直接动态设置

class BaseClass(object):
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age
# 动态设置类属性
setattr(BaseClass,"attr",18)
print(BaseClass.__dict__)

运行结果:{‘attr’: 18}
2)给类设置属性

class BaseClass(object):
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age
var = input("请输入属性名:")
value = 8890
setattr(BaseClass,var,value)
print(BaseClass.__dict__)

运行结果:请输入属性名:KTV
{‘KTV’: 8890}
3)给对象设置属性

class BaseClass(object):
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age
var = input("请输入属性名:")
value = 8890
b1 = BaseClass("木木", 18, "男")
setattr(b1,var,value)
print(b1.__dict__)

运行结果:请输入属性名:KKV
{‘name’: ‘木木’, ‘sex’: 18, ‘age’: ‘男’, ‘KKV’: 8890}

getattr(ojb,属性名,默认值)

在代码执行的过程中获取“类/对象”的属性
需求:根据用户输入的属性名,获取对应的属性值
1)获取类的属性(不存在返回默认值)

class BaseClass(object):
    attr1 = '笨笨'
    attr2 = 18
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age
b1 = BaseClass("木木", 18, "男")
item = input("请输入属性名:")
res = getattr(BaseClass, item, None)
print(res)

运行结果:请输入属性名:attr1
笨笨
请输入属性名:2
None

2)获取对象的属性(不存在返回默认值)

class BaseClass(object):
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age
b1 = BaseClass("木木", 18, "男")
item = input("请输入属性名:")
res = getattr(b1, item, None)
print(res)

运行结果:请输入属性名:sex
18
请输入属性名:1
None

delattr(ojb,属性名)

在代码执行的过程中删除“类/对象”的属性
需求:根据用户输入的属性名,删除对应的属性值
1)删除类的属性

class BaseClass(object):
    attr1 = '笨笨'
    attr2 = 18
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age
b1 = BaseClass("木木", "男", 18)
item = input("请输入属性名:")
delattr(BaseClass, item)
print(BaseClass.__dict__)

运行结果:请输入属性名:attr1
{‘attr2’: 18}
2)删除对象的属性

class BaseClass(object):
    attr1 = '笨笨'
    attr2 = 18
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age
b1 = BaseClass("木木", "男", 18)
item = input("请输入属性名:")
delattr(b1, item)
print(b1.__dict__)

运行结果:请输入属性名:age
{‘name’: ‘木木’, ‘sex’: ‘男’}
3)不支持循环删除属性(报错:RuntimeError)

2.6 多继承

一、定义:一个类同时继承多个父类,括号中填写多个父类

class Base:
    attr1 = 100
    def funca(self):
        print("--------funca------------")
class User:
    attr2 = 200
    def funcb(self):
        print("--------funcb------------")
class MyClass(Base, User):
    pass

m=MyClass()
print(m.attr1)
print(m.attr2)
m.funca()
m.funcb()

运行结果:
100
200
--------funca------------
--------funcb------------
二、当两个父类拥有相同“属性”或“方法”时,使用在括号中先找到的

class Base:
    attr1 = 10
class User:
    attr1 = 100
    attr2 = 200
class MyClass(Base, User):
    pass
print(MyClass.attr1)
print(MyClass.attr2)

运行结果:10
200

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值