python - 面向对象(一)类,对象-类的定义和使用-self详解

目录

1. 什么是面向对象

1.1 常见三种编程范式

1.1.1 函数式编程

1.1.2面向过程编程 (函数)

1.1.3面向对象编程 (OOP-Object Oriented Programming)

1.2 面向过程和面向对象

1.3  面向对象的基本概念

对象:通过类定义的数据结构实例,

类:

实例:

扫描二维码关注公众号,回复: 14468853 查看本文章

1.4  类的基本特点

• 封装(Encapsulation)

• 继承(Inheritance)

• 多态(Polymorphism)

2.  类的定义和使用

2.1  命名的规范

• 类名的规范

• 函数的命名

2.2  类的定义

2.2.1 定义最简单的类:

2.2.2  python2和python3关于新式类的区别

2.2.3  实例化:创建一个类的是实例

2.3  类空间和实例空间

2.4  __init__实例初始化

2.4.1  给ATM类添加 area地域信息

2.5  __new__方法

2.6  单例模式

3.0 self详解

3.1  self不必非写成self

3.2  self可以不写

3.3  例题

示例1:

示例2:

1. 什么是面向对象

1.1 常见三种编程范式

1.1.1 函数式编程

函数可以作为参数传递、修改,或作为返回值
函数内不修改外部变量的状态

1.1.2面向过程编程 (函数)

根据操作数据的语句块来实现功能。

1.1.3面向对象编程 (OOP-Object Oriented Programming)

把数据和功能结合起来,用称为对象的东西包裹起来组织程序的方法。
###################################

1.2 面向过程和面向对象

面向过程是一件事该怎么做,着重于 做什么
面向对象是一件事该让谁来做,着重于 谁去做
###################################

1.3  面向对象的基本概念

对象:通过类定义的数据结构实例,

        对象包括两个数据成员(类变量和实例变量) 和方法
        python一切皆对象,类是对象,实例也是对象

类:

        
        类(class):用来描述具有相同属性和方法的对象的集合
        它定义了该集合中每个对象所共有的属性和方法,对象是类的实例
例:
class ATM():
    # 属性
    money = 50000
    country = "china"
    bank = "gonghang"
    # 方法

    def get_money(self, money):
        print(f'get money:{money}')

实例:

        具体的某个事物,实实在在的例子
        实例化:创建一个类的实例,类的具体对象
# 实例化:创建一个类的实例
# a1,a2 就是实例
a1 = ATM()
a2 = ATM()
print(dir(a1))
print(a1.money, a2.country)
a1.get_money(500)



E:\python\python3.9.1\python.exe E:/tlbb/2022-05-28-python面向对象/01.面向对象.py
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bank', 'country', 'get_money', 'money']
50000 china
get money:500

Process finished with exit code 0
###################################

1.4  类的基本特点

封装(Encapsulation)

在类中对数据的赋值、内部调用对外部用户是透明的。
把一些功能的实现细节不对外暴露

继承(Inheritance)

继承:即一个派生类(derived class)继承基类(base class)的字段和方法。
为实现代码的重用,
一个类可以派生出子类
继承也允许把一个派生类的对象作为一个基类对象对待。

多态(Polymorphism)

接口重用
一个接口,多种实现(重写)
###################################

2.  类的定义和使用

2.1  命名的规范

类名的规范

一般首字母大写(大驼峰)
Person, GoodsInfo

函数的命名

由小写字母和下划线组成
scan_book, drink
###################################

2.2  类的定义

类的定义方式(关键字:class)
python2 --》经典类和新式类
python3 --》新式类
###################################

2.2.1 定义最简单的类:

class A:
    pass
class B():
    pass
class C(object):
    pass
###################################

2.2.2  python2和python3关于新式类的区别

python2只有显示继承object才是新式类,反之就是经典类

所以 class A 和 classB 都是经典类, classC是新式类

在python3里默认都是继承object,所以都是新式类

###################################

2.2.3  实例化:创建一个类的是实例

class ATM():
    # 属性
    money = 50000
    country = "china"
    bank = "gonghang"
    # 方法

    def get_money(self, money):
        print(f'get money:{money}')
a1,a2 就是实例
# 实例化:创建一个类的实例
# a1,a2 就是实例
a1 = ATM()
a2 = ATM()
print(dir(a1))
# 属性访问
print("实例访问".center(20, '*'))
print(a1.money, a2.country)
a1.get_money(500)
print("类访问".center(20, '*'))
print(ATM.money)
print('='*30)

E:\python\python3.9.1\python.exe E:/tlbb/2022-05-28-python面向对象/02.类的定义和使用.py
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bank', 'country', 'get_money', 'money']
********实例访问********
50000 china
get money:500
********类访问*********
50000
==============================
给a1添加属性,只有a1有这个属性,a2没有,ATM也没有,所以执行print会报错
# 给a1添加属性,只有a1有这个属性,a2没有,ATM也没有
a1.area = "hunan"
print(a1.area, a2.area)

Traceback (most recent call last):
  File "E:\tlbb\2022-05-28-python面向对象\02.类的定义和使用.py", line 52, in <module>
    print(a1.area, a2.area)
AttributeError: 'ATM' object has no attribute 'area'
给ATM类添加属性,a1,a2实例都会有这个属性
# 给ATM类添加属性
ATM.color = "blue"
print(a1.color, a2.color)

blue blue
###################################

2.3  类空间和实例空间

类空间和实例空间相互独立,但是实例空间可以访问类空间

class ATM():
    # 属性
    money = 50000
    country = "china"
    bank = "gonghang"
    # 方法

    def get_money(self, money):
        print(f'get money:{money}')

# 类空间和实例空间相互独立,但是实例空间可以访问类空间
print("类空间".center(30, '*'))
print(ATM.__dict__)
print("a1的空间".center(30, '*'))
print(a1.__dict__)
print("a2的空间".center(30, '*'))
print(a2.__dict__)

*************类空间**************
{'__module__': '__main__', 'money': 50000, 'country': 'china', 'bank': 'gonghang', 'get_money': <function ATM.get_money at 0x000001E9A3C76AF0>, '__dict__': <attribute '__dict__' of 'ATM' objects>, '__weakref__': <attribute '__weakref__' of 'ATM' objects>, '__doc__': None, 'color': 'blue'}
************a1的空间*************
{'area': 'hunan'}
************a2的空间*************
{}
指针可以访问类空间,但是不能修改类空间
# 指针可以访问类空间,但是不能修改类空间
a1.money = 20000
print(a1.money, a2.money)

20000 50000
类创建的时候会生产类空间
实例化对象生产实例空间,不同的实例空间,空间都是独立的
实例查找属性方法的时候,先在实例空间查找,找不到就去类空间查找
类空间找不到,就去父类空间找
实例空间会有一个类对象指针,通过这个指针实例就可以访问类的属性方法了
###################################

2.4  __init__实例初始化

这个名称的开始和结尾都是双下划线。
这个方法可以用来对你的对象做一些你希望的 初始化 任务。
__init__()方法是一种特殊的方法,被称为类的构造函数或初始化方法,
它在类的一个对象被建立后,自动运行。
###################################

2.4.1  给ATM类添加 area地域信息

class ATM():
    # 类属性
    money = 50000
    country = "china"
    bank = "gonghang"

    # 这个area是形参
    def __init__(self, area):
        # 这个area是实例属性
        self.area = area
    # 方法

    def get_money(self, money):
        print(f'get money:{money}')


# 实例化
atm1 = ATM("hunan")
atm2 = ATM("hubei")
print(atm1.area, atm2.area)

E:\python\python3.9.1\python.exe E:/tlbb/2022-05-28-python面向对象/02.类的定义和使用.py
hunan hubei

Process finished with exit code 0
###################################

2.5  __new__方法

这个名称的开始和结尾都是双下划线。
这个方法用来创建一个实例,一般情况下都不会重写。
class ATM():
    # 类属性
    money = 50000
    country = "china"
    bank = "gonghang"

    # 这个area是形参
    def __init__(self, area):
        # 这个area是实例属性
        print("this is init>>>>>")
        self.area = area

    def __new__(cls, *args, **kwargs):
        print("this is new method:", cls)
        print(args, kwargs)
        # cls 代表当前类
        return object.__new__(A)
    # 方法

    def get_money(self, money):
        print(f'get money:{money}')


atm1 = ATM("changsha")
# 这里因为 __new__没有
atm1.get_money(500)
print(atm1)
###################################

2.5.1  总结


__new__ 是创建实例的方法
__init__是创建好的实例进行初始化的方法
__new__方法必须要传入一个参数(cls),代表当前类
__init__的self就表示__new__返回的实例, __init__再对这份实例进行初始化
子类没有定义__new__,就会去找父类的__new__
新式类才有__new__
如果实例化对象和本身class不一致, __init__不会执行

__new__方法属于静态方法
__init__方法是实例方法

###################################

2.6  单例模式

无论实例化多少次,都返回同一个对象实例

# 单例模式
# 无论实例化多少次,都返回同一个对象实例
# __new__

# 实例空间从class开始就已经存在,
class Danli:
    instance = None

    def __new__(cls, *args, **kwargs):
        if cls.instance is None:
            cls.instance = object.__new__(cls)
        return cls.instance


# 创建一个实例空间
d1 = Danli()
d2 = Danli()
print(id(d1), id(d2))

E:\python\python3.9.1\python.exe E:/tlbb/2022-05-28-python面向对象/02.类的定义和使用.py
2309763436448 2309763436448

Process finished with exit code 0

3.0 self详解

self代表当前的对象,而不是类

class User():
    name = "sc"

    def info(self):
        print(f"i am {self.name}")
        print(self)
        print(self.__class__)


user1 = User()
user1.info()
user2 = User()
user2.info()

E:\python\python3.9.1\python.exe E:/tlbb/2022-05-28-python面向对象/03.self详解.py
i am sc
<__main__.User object at 0x00000263B7210FD0>
<class '__main__.User'>
i am sc
<__main__.User object at 0x00000263B7210FA0>
<class '__main__.User'>

Process finished with exit code 0
###################################

3.1  self不必非写成self

只是一般约定俗成使用self

class User():
    name = "sc"

    def info(this):
        print(f"i am {this.name}")
        print(this)
        print(this.__class__)

user1 = User()
user1.info()

E:\python\python3.9.1\python.exe E:/tlbb/2022-05-28-python面向对象/03.self详解.py
i am sc
<__main__.User object at 0x000001DF0F44FE80>
<class '__main__.User'>

Process finished with exit code 0
###################################

3.2  self可以不写

但是不写self的话,无法使用实例进行调用,

因为实例调用的时候会自动将实例作为一个参数传进去

# self 可以不写
# 但是不可以使用实例进行调用,因为实例调用会自动将实例作为一个参数穿进去
class User():
    name = "sc"

    def info(this):
        print(f"i am {this.name}")
        print(this)
        print(this.__class__)

    def info2():
        print("this is info2")


user1 = User()
user1.info()  # ---->User.info(user1)
user1.info2()  # --->user.info2(user1)
user2 = User()
user2.info()  # --->User.info(user2)

E:\python\python3.9.1\python.exe E:/tlbb/2022-05-28-python面向对象/03.self详解.py
Traceback (most recent call last):
  File "E:\tlbb\2022-05-28-python面向对象\03.self详解.py", line 53, in <module>
    user1.info2()  # --->user.info2(user1)
TypeError: info2() takes 0 positional arguments but 1 was given
i am sc
<__main__.User object at 0x0000021C0AFD0FD0>
<class '__main__.User'>

Process finished with exit code 1
###################################

3.3  例题

# 用户名
# 属性 名字, 密码,余额
# 行为
#       购物 --》余额减少  商品库存减少
# 商品类
# 属性    类别, 名字, 单价, 库存(斤)

示例1:

实现了基本功能,但是没有体现面向对象 谁去做的思想
不应该把公共属性写死,最好使用__init__对实例进行初始化
class User():
    goods_name = 'apple'
    goods_price = 5
    goods_num = 500

    def __init__(self, name, pd):
        if name == 'wang' and pd == '123456':
            print("sucessfully login".center(30, '*'))
            print(f"今日商品: {self.goods_name}")
            print(f"商品单价: {self.goods_price}")
            print(f"商品数量: {self.goods_num}")
            self.flag = 1
            self.money = 500
        else:
            print("error to login")

    def buy_goods(self, goodname, goodcount):
        if self.flag == 1:
            self.goods_num -= goodcount
            print(f"当前实时库存:{self.goods_num}")
            self.money = self.money - goodcount * self.goods_price
            print(f"您当前余额:{self.money}")


user1 = User('wang', '123456')
user1.buy_goods('apple', 1)

******sucessfully login*******
今日商品: apple
商品单价: 5
商品数量: 500
当前实时库存:499
您当前余额:495

Process finished with exit code 0
###################################

示例2:

面向对象的思想最重要的是谁去做,而不是怎么做!

class User:
    def __init__(self, name, passwd, money):
        self.name = name
        self.passwd = passwd
        self.money = money

    def buy_goods(self, good, weight):
        if weight > good.store:
            print("库存不足!")
        else:
            pay = weight * good.price
            if self.money >= pay:
                self.money -= pay
                good.store -= weight
                print(f"购买成功,{self.name}剩余{self.money}元,"
                      f"{good.product_name},剩余库存{good.store}斤")
            else:
                print("余额不足!")


class Goods:
    def __init__(self, classify, product_name, price, store):
        self.classify = classify
        self.product_name = product_name
        self.price = price
        self.store = store


user1 = User("zhangj", "123456", 5000)
user2 = User("wangsh", "1234567", 8000)

apple = Goods("fruits", "apple", 8, 30)
orange = Goods("fruits", "orange", 4, 100)

user1.buy_goods(apple, 3)

E:\python\python3.9.1\python.exe E:/tlbb/2022-05-28-python面向对象/03.self详解.py
购买成功,zhangj剩余4976元,apple,剩余库存27斤

Process finished with exit code 0

猜你喜欢

转载自blog.csdn.net/qq_48391148/article/details/125020550
今日推荐