当前位置:   article > 正文

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

python 类 self

目录

1. 什么是面向对象

1.1 常见三种编程范式

1.1.1 函数式编程

1.1.2面向过程编程 (函数)

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

1.2 面向过程和面向对象

1.3  面向对象的基本概念

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

类:

实例:

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):用来描述具有相同属性和方法的对象的集合
        它定义了该集合中每个对象所共有的属性和方法,对象是类的实例
例:
  1. class ATM():
  2. # 属性
  3. money = 50000
  4. country = "china"
  5. bank = "gonghang"
  6. # 方法
  7. def get_money(self, money):
  8. print(f'get money:{money}')

实例:

        具体的某个事物,实实在在的例子
        实例化:创建一个类的实例,类的具体对象
  1. # 实例化:创建一个类的实例
  2. # a1,a2 就是实例
  3. a1 = ATM()
  4. a2 = ATM()
  5. print(dir(a1))
  6. print(a1.money, a2.country)
  7. a1.get_money(500)
  8. E:\python\python3.9.1\python.exe E:/tlbb/2022-05-28-python面向对象/01.面向对象.py
  9. ['__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']
  10. 50000 china
  11. get money:500
  12. 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 定义最简单的类:

  1. class A:
  2. pass
  3. class B():
  4. pass
  5. class C(object):
  6. pass
###################################

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

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

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

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

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

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

  1. class ATM():
  2. # 属性
  3. money = 50000
  4. country = "china"
  5. bank = "gonghang"
  6. # 方法
  7. def get_money(self, money):
  8. print(f'get money:{money}')
a1,a2 就是实例
  1. # 实例化:创建一个类的实例
  2. # a1,a2 就是实例
  3. a1 = ATM()
  4. a2 = ATM()
  5. print(dir(a1))
  6. # 属性访问
  7. print("实例访问".center(20, '*'))
  8. print(a1.money, a2.country)
  9. a1.get_money(500)
  10. print("类访问".center(20, '*'))
  11. print(ATM.money)
  12. print('='*30)
  13. E:\python\python3.9.1\python.exe E:/tlbb/2022-05-28-python面向对象/02.类的定义和使用.py
  14. ['__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']
  15. ********实例访问********
  16. 50000 china
  17. get money:500
  18. ********类访问*********
  19. 50000
  20. ==============================
给a1添加属性,只有a1有这个属性,a2没有,ATM也没有,所以执行print会报错
  1. # 给a1添加属性,只有a1有这个属性,a2没有,ATM也没有
  2. a1.area = "hunan"
  3. print(a1.area, a2.area)
  4. Traceback (most recent call last):
  5. File "E:\tlbb\2022-05-28-python面向对象\02.类的定义和使用.py", line 52, in <module>
  6. print(a1.area, a2.area)
  7. AttributeError: 'ATM' object has no attribute 'area'
给ATM类添加属性,a1,a2实例都会有这个属性
  1. # 给ATM类添加属性
  2. ATM.color = "blue"
  3. print(a1.color, a2.color)
  4. blue blue
###################################

2.3  类空间和实例空间

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

  1. class ATM():
  2. # 属性
  3. money = 50000
  4. country = "china"
  5. bank = "gonghang"
  6. # 方法
  7. def get_money(self, money):
  8. print(f'get money:{money}')
  9. # 类空间和实例空间相互独立,但是实例空间可以访问类空间
  10. print("类空间".center(30, '*'))
  11. print(ATM.__dict__)
  12. print("a1的空间".center(30, '*'))
  13. print(a1.__dict__)
  14. print("a2的空间".center(30, '*'))
  15. print(a2.__dict__)
  16. *************类空间**************
  17. {'__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'}
  18. ************a1的空间*************
  19. {'area': 'hunan'}
  20. ************a2的空间*************
  21. {}
指针可以访问类空间,但是不能修改类空间
  1. # 指针可以访问类空间,但是不能修改类空间
  2. a1.money = 20000
  3. print(a1.money, a2.money)
  4. 20000 50000
类创建的时候会生产类空间
实例化对象生产实例空间,不同的实例空间,空间都是独立的
实例查找属性方法的时候,先在实例空间查找,找不到就去类空间查找
类空间找不到,就去父类空间找
实例空间会有一个类对象指针,通过这个指针实例就可以访问类的属性方法了
###################################

2.4  __init__实例初始化

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

2.4.1  给ATM类添加 area地域信息

  1. class ATM():
  2. # 类属性
  3. money = 50000
  4. country = "china"
  5. bank = "gonghang"
  6. # 这个area是形参
  7. def __init__(self, area):
  8. # 这个area是实例属性
  9. self.area = area
  10. # 方法
  11. def get_money(self, money):
  12. print(f'get money:{money}')
  13. # 实例化
  14. atm1 = ATM("hunan")
  15. atm2 = ATM("hubei")
  16. print(atm1.area, atm2.area)
  17. E:\python\python3.9.1\python.exe E:/tlbb/2022-05-28-python面向对象/02.类的定义和使用.py
  18. hunan hubei
  19. Process finished with exit code 0
###################################

2.5  __new__方法

这个名称的开始和结尾都是双下划线。
这个方法用来创建一个实例,一般情况下都不会重写。
  1. class ATM():
  2. # 类属性
  3. money = 50000
  4. country = "china"
  5. bank = "gonghang"
  6. # 这个area是形参
  7. def __init__(self, area):
  8. # 这个area是实例属性
  9. print("this is init>>>>>")
  10. self.area = area
  11. def __new__(cls, *args, **kwargs):
  12. print("this is new method:", cls)
  13. print(args, kwargs)
  14. # cls 代表当前类
  15. return object.__new__(A)
  16. # 方法
  17. def get_money(self, money):
  18. print(f'get money:{money}')
  19. atm1 = ATM("changsha")
  20. # 这里因为 __new__没有
  21. atm1.get_money(500)
  22. print(atm1)
###################################

2.5.1  总结


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

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

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

2.6  单例模式

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

  1. # 单例模式
  2. # 无论实例化多少次,都返回同一个对象实例
  3. # __new__
  4. # 实例空间从class开始就已经存在,
  5. class Danli:
  6. instance = None
  7. def __new__(cls, *args, **kwargs):
  8. if cls.instance is None:
  9. cls.instance = object.__new__(cls)
  10. return cls.instance
  11. # 创建一个实例空间
  12. d1 = Danli()
  13. d2 = Danli()
  14. print(id(d1), id(d2))
  15. E:\python\python3.9.1\python.exe E:/tlbb/2022-05-28-python面向对象/02.类的定义和使用.py
  16. 2309763436448 2309763436448
  17. Process finished with exit code 0

3.0 self详解

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

  1. class User():
  2. name = "sc"
  3. def info(self):
  4. print(f"i am {self.name}")
  5. print(self)
  6. print(self.__class__)
  7. user1 = User()
  8. user1.info()
  9. user2 = User()
  10. user2.info()
  11. E:\python\python3.9.1\python.exe E:/tlbb/2022-05-28-python面向对象/03.self详解.py
  12. i am sc
  13. <__main__.User object at 0x00000263B7210FD0>
  14. <class '__main__.User'>
  15. i am sc
  16. <__main__.User object at 0x00000263B7210FA0>
  17. <class '__main__.User'>
  18. Process finished with exit code 0
###################################

3.1  self不必非写成self

只是一般约定俗成使用self

  1. class User():
  2. name = "sc"
  3. def info(this):
  4. print(f"i am {this.name}")
  5. print(this)
  6. print(this.__class__)
  7. user1 = User()
  8. user1.info()
  9. E:\python\python3.9.1\python.exe E:/tlbb/2022-05-28-python面向对象/03.self详解.py
  10. i am sc
  11. <__main__.User object at 0x000001DF0F44FE80>
  12. <class '__main__.User'>
  13. Process finished with exit code 0
###################################

3.2  self可以不写

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

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

  1. # self 可以不写
  2. # 但是不可以使用实例进行调用,因为实例调用会自动将实例作为一个参数穿进去
  3. class User():
  4. name = "sc"
  5. def info(this):
  6. print(f"i am {this.name}")
  7. print(this)
  8. print(this.__class__)
  9. def info2():
  10. print("this is info2")
  11. user1 = User()
  12. user1.info() # ---->User.info(user1)
  13. user1.info2() # --->user.info2(user1)
  14. user2 = User()
  15. user2.info() # --->User.info(user2)
  16. E:\python\python3.9.1\python.exe E:/tlbb/2022-05-28-python面向对象/03.self详解.py
  17. Traceback (most recent call last):
  18. File "E:\tlbb\2022-05-28-python面向对象\03.self详解.py", line 53, in <module>
  19. user1.info2() # --->user.info2(user1)
  20. TypeError: info2() takes 0 positional arguments but 1 was given
  21. i am sc
  22. <__main__.User object at 0x0000021C0AFD0FD0>
  23. <class '__main__.User'>
  24. Process finished with exit code 1
###################################

3.3  例题

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

示例1:

实现了基本功能,但是没有体现面向对象 谁去做的思想
不应该把公共属性写死,最好使用__init__对实例进行初始化
  1. class User():
  2. goods_name = 'apple'
  3. goods_price = 5
  4. goods_num = 500
  5. def __init__(self, name, pd):
  6. if name == 'wang' and pd == '123456':
  7. print("sucessfully login".center(30, '*'))
  8. print(f"今日商品: {self.goods_name}")
  9. print(f"商品单价: {self.goods_price}")
  10. print(f"商品数量: {self.goods_num}")
  11. self.flag = 1
  12. self.money = 500
  13. else:
  14. print("error to login")
  15. def buy_goods(self, goodname, goodcount):
  16. if self.flag == 1:
  17. self.goods_num -= goodcount
  18. print(f"当前实时库存:{self.goods_num}")
  19. self.money = self.money - goodcount * self.goods_price
  20. print(f"您当前余额:{self.money}")
  21. user1 = User('wang', '123456')
  22. user1.buy_goods('apple', 1)
  23. ******sucessfully login*******
  24. 今日商品: apple
  25. 商品单价: 5
  26. 商品数量: 500
  27. 当前实时库存:499
  28. 您当前余额:495
  29. Process finished with exit code 0
###################################

示例2:

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

  1. class User:
  2. def __init__(self, name, passwd, money):
  3. self.name = name
  4. self.passwd = passwd
  5. self.money = money
  6. def buy_goods(self, good, weight):
  7. if weight > good.store:
  8. print("库存不足!")
  9. else:
  10. pay = weight * good.price
  11. if self.money >= pay:
  12. self.money -= pay
  13. good.store -= weight
  14. print(f"购买成功,{self.name}剩余{self.money}元,"
  15. f"{good.product_name},剩余库存{good.store}斤")
  16. else:
  17. print("余额不足!")
  18. class Goods:
  19. def __init__(self, classify, product_name, price, store):
  20. self.classify = classify
  21. self.product_name = product_name
  22. self.price = price
  23. self.store = store
  24. user1 = User("zhangj", "123456", 5000)
  25. user2 = User("wangsh", "1234567", 8000)
  26. apple = Goods("fruits", "apple", 8, 30)
  27. orange = Goods("fruits", "orange", 4, 100)
  28. user1.buy_goods(apple, 3)
  29. E:\python\python3.9.1\python.exe E:/tlbb/2022-05-28-python面向对象/03.self详解.py
  30. 购买成功,zhangj剩余4976元,apple,剩余库存27
  31. Process finished with exit code 0

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/883426
推荐阅读
相关标签
  

闽ICP备14008679号