笔记目录
Python 学习笔记 上
面向对象和异常
面向对象
基本理论
# _*_coding:utf-8_*_
# !/usr/bin/env python3
# 基本理论
# 什么是对象:万物皆对象
# 对象是具体的物体:拥有属性,拥有行为,把很多零散的东西封装成一个整体
# 比如张三:
# 属性:姓名、身高、年龄、体重
# 行为:走、跑、跳
# 在python中的体现:python是一门彻底的面向对象编程(oop)语言
# 面向对象和面向过程:都是解决问题的思路
# 面向过程:在解决问题的时候,关注的是解决问题的每一个步骤
# 面向对象:在解决问题的时候,关注的是解决问题所需要的对象
# 对比:
# 面向过程和面向对象都是解决问题的一种思想:面向对象是面向过程的封装
# 面向过程编程最重要的是:按步骤划分,将一个任务划分成具体的步骤
# 面向对象编程最重要的是:按功能对象划分,找到对象,确定对象的属性和行为
# 如何从面相过程编程过渡到面向对象编程:
# 1.列举出一个任务具体的步骤
# 2.分离这些实现步骤中的功能代码块
# 3.将这些功能代码块划分到一个对象中
# 4.根据这些对象及行为,抽象出对应的类(设计类)
# 什么是类:某一个具体对象特征的抽象
# 例如
# 张三这个具体的人:
# 属性:年龄:18 身高:180 体重:150···
# 行为:吃:抽烟 喝:白酒 赌 嫖 打架···
# 由张三抽象出来的类:不良青年:
# 属性:年龄 身高 体重···
# 行为:吃 喝 嫖 赌···
# 类的作用:根据抽象出来的类生产具体的对象
# 例如:
# 类:不良青年:
# 属性:年龄 身高 体重···
# 行为:吃 喝 嫖 赌···
# 形成对象:
# 张三:不同的属性和不同的行为
# 李四:不同的属性和不同的行为
# 王二麻子:不同的属性和不同的行为
# 类的组成:
# 名称
# 属性
# 方法
# 注意:以上的属性和方法都是抽象的概念(不良青年而不是具体的张三李四);在产生对象之后,对象才具有具体的属性值和方法实现
# 生活中的类:
# 钱:1毛,1元,5元,10元···
# 汽车品牌:大众,奥拓,马自达···
# 树:桃树、李子树、杏子书···
# 对象和类的关系:对象==>抽象==>类==>实例化==>对象
定义类
# 定义类
# _*_coding:utf-8_*_
# !/usr/bin/env python3
# 语法:
# class ClassName[()]:
# pass
# 注意:
# python中的类分为经典类和新式类
# 类的命名需要坚持大驼峰标识,单词首字母大写
# '()'可以选择加或者不加,加'()'是继承
根据类实例化对象
# _*_coding:utf-8_*_
# !/usr/bin/env python3
# 根据一个类实例化一个对象
class Tree:
pass
# ClassName不仅是类名,也是变量名
tree = Tree() # tree就是通过类创建的一个对象
# 在pycharm下使用ClassName + .pri + TAB键 == print(ClassName)
print(tree)
Tree = 666
print(type(Tree), Tree)
print(tree.__class__)
print(tree)
# <__main__.Tree object at 0x00000265C9A8A400>
# <class 'int'> 666
# <class '__main__.Tree'>
# <__main__.Tree object at 0x00000265C9A8A400>
属性相关
属性的含义以及和变量的区别
# _*_coding:utf-8_*_
# !/usr/bin/env python3
# 属性相关:
# 属性和变量的区别及判定依据:
# 区别:
# 概念:
# 变量是'可以改变的量值'
# 属性是'属于某个对象的特性'
# 访问权限:
# 变量:根据不同的位置,具有不同的访问权限(局部变量、全局变量···)
# 属性:只能通过对象来进行访问:
# 所以必须先找到对象
# 对象也是通过变量名来引用;因为是变量,也存在访问权限
# 判定依据:是否存在宿主(根据宿主的不同划分为类属性和对象属性)
对象属性的增删改查
# _*_coding:utf-8_*_
# !/usr/bin/env python3
# 对象属性:
# 增加对象属性:
# 语法:
# 方式一:ClassName.object = value
# 方式一:通过类的初始化方法(构造方法):__init__方法(python对象的生命周期)
class ProvincialCapital:
pass
captial = ProvincialCapital()
captial.Sichuan = '成都'
captial.HuNan = '长沙'
captial.HuBei = '武汉'
captial.Hei_Long_Jiang_city = ['哈尔滨', '齐齐哈尔', '牡丹江', '绥芬河', '佳木斯', '同江', '大庆']
# 查询对象属性:
# 语法:object.attributeName / object.__dict__ / object.attribute.属性可使用的查询方法
# 返回值:object.attributeName返回的是单个属性的值,object.__dict__以键值对的形式返回对象内所有属性和值,object.attribute.属性可使用的查询方法的返回值由具体的方法决定
# 注意:如果访问不存在的值会报错:AttributeError
print(captial.Sichuan)
print(captial.__dict__) # object.__dict__以键值对的形式返回对象内所有的属性
print(captial.Hei_Long_Jiang_city[1: 5])
# 成都
# {'Sichuan': '成都', 'HuNan': '长沙', 'HuBei': '武汉', 'Hei_Long_Jiang_city': ['哈尔滨', '齐齐哈尔', '牡丹江', '绥芬河', '佳木斯', '同江', '大庆']}
# ['齐齐哈尔', '牡丹江', '绥芬河', '佳木斯']
# 修改对象属性:
# 直接修改:object.attribute = newValue # 会修改属性的储存地址
# 访问修改:object.attribute.属性可使用的修改方式 # 根据属性的数据类型决定是否会修改储存地址
captial.Si_Chuan_city = ['成都', '绵阳', '攀枝花', '德阳', '巴中']
ID0 = id(captial.Si_Chuan_city)
captial.Si_Chuan_city = ['成都', '绵阳', '攀枝花', '德阳', '巴中', '自贡', '遂宁']
ID1 = id(captial.Si_Chuan_city)
print(ID0 == ID1)
captial.Si_Chuan_city.append('眉山')
ID2 = id(captial.Si_Chuan_city)
print(ID1 == ID2)
# False
# True
# 删除对象属性:
# 语法:
# del语句:直接删除整个属性或者属性内的多个值
# object.attributeName.属性可使用的删除方法 # 具体删除多少根据使用的方法而定
captial.Si_Chuan_city.remove('巴中')
print(captial.Si_Chuan_city)
# ['成都', '绵阳', '攀枝花', '德阳', '自贡', '遂宁', '眉山']
del captial.Hei_Long_Jiang_city
del captial.Si_Chuan_city[:5]
print(captial.__dict__)
# {'Sichuan': '成都', 'HuNan': '长沙', 'HuBei': '武汉', 'Si_Chuan_city': ['遂宁', '眉山']}
# 注意:不同的对象之间不能互相访问属性,否则会报错:AttributeError
类属性的增删改查
# 类属性:万物皆对象,类也是一种特殊的对象
# 增加类的属性:
# 方式一:ClassName.attribute = value
# 方式二:
# class ClassName:
# attribute0 = value0
# attribute1 = value1
# ···
# attribute = value
class ProvincialCity:
SiChuan = '成都'
HuNan = '长沙'
HuBei = '武汉'
ProvincialCity.HeBei = '石家庄'
# 查找类的属性:
# 方式一:通过类访问:ClassName.attribute
# 方式二:通过类创建的对象访问:object.attribute
# 注意:
# python查找对象的机制:
# 优先到对象自身查找属性,如果找到了就结束
# 如果没找到,则根据__class__找到创建对象的类,到这个类里面去查找
# 如果更改对象所属的类,不能查询原类的内容,否则会报错:AttributeError
class Chinese:
compulsoryOne = '离骚'
compulsoryTwo = '赤壁赋'
compulsoryThree = '过秦论'
class Math:
ElectiveOne = '逻辑、圆锥曲线、导数'
ElectiveFour = '不等式'
Title = Chinese()
Title.compulsoryOne = '沁园春·长沙'
print(Chinese.compulsoryOne, Title.compulsoryTwo)
print(Title.compulsoryOne, Chinese.compulsoryOne)
# 离骚 赤壁赋
# 沁园春·长沙 离骚
# 修改对象属性:
# 语法:ClassName.attribute = newValue
# 注意:不能使用object.attribute = newValue,这种做法只能修改对象的属性,如果这个属性不存在,那么将新建
Math.ElectiveFour = '不等式、柯西不等式'
print(Math.ElectiveFour)
Title.__class__ = Math # object.__class__ = ClassName修改对象的类
Title.ElectiveFour = '不等式和绝对值不等式、证明不等式的方法、柯西不等式、排序不等式、数学归纳法证明不等式'
print(Math.ElectiveFour) # 如果Math.ElectiveFour的值改变,那么object.attribute = newValue方法有效
print(Title.__dict__)
# 不等式、柯西不等式
# 不等式、柯西不等式
# {'compulsoryOne': '沁园春·长沙', 'ElectiveFour': '不等式和绝对值不等式、证明不等式的方法、柯西不等式、排序不等式、数学归纳法证明不等式'}
# 删除对象属性:
# 语法:del ClassName.attribute
# 注意:不能通过del object.attribute删除,该方法只能删除object自己的属性
del Math.ElectiveOne
print(Math.__dict__)
# {'__module__': '__main__', 'ElectiveFour': '不等式、柯西不等式', '__dict__': <attribute '__dict__' of 'Math' objects>, '__weakref__': <attribute '__weakref__' of 'Math' objects>, '__doc__': None}
# 注意
# 注意:类属性的储存:
# 一般情况下属性存储在__dict__的字典中(但有些内置对象没有__dict__属性)
# 由类创建的对象可以直接修改__dict__属性
# 但类对象的__dict__只能读:一般无法修改,否则会报错:AttributeError: attribute '__dict__' of 'type'
# objects is not writable,可以通过setatttr方法修改,
class UserInformation:
name = 'David'
age = 19
print(UserInformation.__dict__)
# {'__module__': '__main__', 'name': 'David', 'age': 19, '__dict__': <attribute '__dict__' of 'UserInformation' objects>, '__weakref__': <attribute '__weakref__' of 'UserInformation' objects>, '__doc__': None}
address = UserInformation()
address.__dict__ = {
'address': '40N, 10E'}
print(address.address)
# 40N, 40N10E10E
# 类属性被各个对象共享
限制对象属性
```python
# _*_coding:utf-8_*_
# !/usr/bin/env python3
# 限制对象属性
# 语法:
# class ClassName:
# __slots__ = [attributeName0, attributeName1, ···]
# 注意:后续添加的属性必须是__slots__列表里面必须有的,否则会报错:ValueError: xxx in __slots__ conflicts with class variable
方法相关
概念及划分
# _*_coding:utf-8_*_
# !/usr/bin/env python3
# 方法的概念:
# 描述一个目标的行为动作,和函数非常相似:
# 都封装了一系列动作,被调用了之后执行这些动作;主要的区别在于调用的方式
# 方法的划分:
# 实例方法:默认第一个参数接收一个实例
# 类方法:默认第一个参数接收一个类
# 静态方法:第一个参数没有限制
# 注意事项:
# 划分的依据:方法的第一个参数必须要接收的数据类型
# 不管是哪种方法,都储存在类的__dict__属性中,没有储存在实例中
# 不同类型的方法调用方式也不同:
# 但都坚持一个原则:无论是我们传递还是解释器自动处理;最重要保证方法接收到的
# 第一个参数的类型是自己想要的类型
实例方法
# _*_coding:utf-8_*_
# !/usr/bin/env python3
# 实例方法
# 语法:
# class ClassName:
# def function(self, ···):
# pass
# 调用:
# 标准调用:object.function()
# 使用实例调用实例方法,不用手动传递,解释器会自动将调用对象本身传递过去
# 其他调用:本质都是直接找到函数本身来调用
# 使用类调用:ClassName.function()
# 其他调用:
# func = ClassName.function
# func()
# 注意:如果实例方法没有接受任何参数会报错:TypeError: unary_function() takes 0 positional arguments but 4 were given
# 解释器自动传递了参数,但是实例方法不需要接受参数
class MathCompulsoryOne:
def unary_function(self, k, x, b):
print('一元一次函数公式是f(x) = {0}x+{2},当x = {1},f(x) = {3}'.format(k, x, b, k * x + b))
# 标准调用
func = MathCompulsoryOne()
func.unary_function(6, 2, 10)
# 使用类调用:
MathCompulsoryOne.unary_function(MathCompulsoryOne, 6, 2, 10)
# 其他调用:
Func = func.unary_function
Func(6, 2, 10)
# 一元一次函数公式是f(x) = 6x+10,当x = 2,f(x) = 22
# 一元一次函数公式是f(x) = 6x+10,当x = 2,f(x) = 22
# 一元一次函数公式是f(x) = 6x+10,当x = 2,f(x) = 22
类方法
# _*_coding:utf-8_*_
# !/usr/bin/env python3
# 类方法
# 语法:
# class ClassName:
# @classmethod
# def function(self, ···)
# pass
# 调用:
# 标准方法:
# 方式一:ClassName.function()
# 方式二:
# func = ClassName()
# func.function()
# 间接调用:
# func = ClassName.function
# func()
class MathCompulsoryOne:
@classmethod
def unary_function(cls, k, x, b):
if b < 0:
print('一元一次函数公式是f(x) = {0}x{2},当x = {1},f(x) = {3}'.format(k, x, b, k * x + b))
else:
print('一元一次函数公式是f(x) = {0}x+{2},当x = {1},f(x) = {3}'.format(k, x, b, k * x + b))
func = MathCompulsoryOne()
# 方式一:
MathCompulsoryOne.unary_function(4, 10, -30)
# 一元一次函数公式是f(x) = 4x-30,当x = 10,f(x) = 10
# 方式二
func.unary_function(2, 5, 7)
# 一元一次函数公式是f(x) = 2x+7,当x = 5,f(x) = 17
# 间接调用:
func = MathCompulsoryOne.unary_function
func(4, 5, 6)
# 一元一次函数公式是f(x) = 4x+6,当x = 5,f(x) = 26
静态方法
# _*_coding:utf-8_*_
# !/usr/bin/env python3
# 静态方法
# 语法:
# class ClassName:
# @staticmethod
# def function(···):
# pass
# 调用:
# 标准方式:
# 方式一:ClassName.function()
# 方式二:
# func = ClassName()
# func.function()
# 其他调用:
# 方式三:
# func = ClassName.function
# func()
class MathCompulsoryOne:
@staticmethod
def unary_function(k, x, b):
if b < 0:
print('一元一次函数公式是f(x) = {0}x{2},当x = {1},f(x) = {3}'.format(k, x, b, k * x + b))
else:
print('一元一次函数公式是f(x) = {0}x+{2},当x = {1},f(x) = {3}'.format(k, x, b, k * x + b))
# 方式一:
MathCompulsoryOne.unary_function(4, 5, 6)
# 一元一次函数公式是f(x) = 4x+6,当x = 5,f(x) = 26
# 方式二:
func = MathCompulsoryOne()
func.unary_function(7, 8, 8)
# 一元一次函数公式是f(x) = 7x+8,当x = 8,f(x) = 64
# 方式三:
func = MathCompulsoryOne.unary_function
func(1, 2, 3)
# 一元一次函数公式是f(x) = 1x+3,当x = 2,f(x) = 5
注意事项
# _*_coding:utf-8_*_
# !/usr/bin/env python3
# 注意事项:不同类型的方法对不同类型属性的访问权限(一般情况下)
# 实例方法:类和实例(对象)的属性都能访问
# 类方法:只能访问类的属性
# 静态方法:类和实例(对象)的属性都不能访问
# 此处和类和实例(对象)的查询有关,类方法和实例方法会将类和实例(对象)当作参数传递进去,访问权限自然取决于类和实例(对象)的
# 访问方式,而静态方法不会讲类和实例(对象)传递进去,因而谁都不能访问
# 如果调用了不能调用的属性会报错:AttributeError
class ProvinceCity:
Si_Chuan = '成都市、自贡市、攀枝花市、泸州市、德阳市、绵阳市、广元市、遂宁市、内江市、乐山市、南充市···'
Hu_Nan = '长沙、株洲、湘潭、怀化···'
def si_chuan(self):
print(self.Si_Chuan)
print(self.Si_Chuan_Other)
@classmethod
def hu_nan(cls):
print(cls.Hu_Nan)
@staticmethod
def blank():
print(ProvinceCity.Hu_Nan)
print(Province_city.Si_Chuan_Other)
# 实例方法调用类和实例属性
Province_city = ProvinceCity()
Province_city.Si_Chuan_Other = '眉山市、宜宾市、广安市、达州市、雅安市、巴中市、资阳市、阿坝藏族羌族自治州、甘孜藏族自治州、凉山彝族自治州'
Province_city.si_chuan()
# 成都市、自贡市、攀枝花市、泸州市、德阳市、绵阳市、广元市、遂宁市、内江市、乐山市、南充市···
# 眉山市、宜宾市、广安市、达州市、雅安市、巴中市、资阳市、阿坝藏族羌族自治州、甘孜藏族自治州、凉山彝族自治州
# 类方法调用类属性
ProvinceCity.hu_nan()
# 长沙、株洲、湘潭、怀化···
# 静态方法调用类或者实例属性必须先查找
ProvinceCity.blank()
# 长沙、株洲、湘潭、怀化···
# 眉山市、宜宾市、广安市、达州市、雅安市、巴中市、资阳市、阿坝藏族羌族自治州、甘孜藏族自治州、凉山彝族自治州
类的补充
元类
# _*_coding:utf-8_*_
# !/usr/bin/env python3
# 元类:type
# 概念:创建类对象的类:类也是对象,是有另一个类创建出来的
num = 1
print(num.__class__)
print(num.__class__.__class__)
class Class:
pass
print(Class.__class__)
# <class 'int'>
# <class 'type'>
# <class 'type'>
创建类的方法
# _*_coding:utf-8_*_
# !/usr/bin/env python3
# 创建类对象:
# 语法:
# 方式一:
# class ClassName:
# pass
# 方式二:
# ClassName = type(name, tuple, dict)
# 参数:name:类的名称, tuple:,dict:类包含的属性
# 方式二:
def address(self):
print(self.Address)
@classmethod
def age(cls):
print(cls.Age)
@staticmethod
def sex():
print('male')
PersonInformation = type('Jack', (), {
'Name': 'Jack', 'sex': sex, 'address': address, 'Age': 17, 'age': age})
print(PersonInformation.__dict__)
# {'Name': 'Jack', 'sex': <staticmethod object at 0x0000012E594AD520>, 'address': <function address at 0x0000012E5950B040>, 'Age': 17, 'age': <classmethod object at 0x0000012E59435CD0>, '__module__': '__main__', '__dict__': <attribute '__dict__' of 'Jack' objects>, '__weakref__': <attribute '__weakref__' of 'Jack' objects>, '__doc__': None}
PersonAddress = PersonInformation()
PersonAddress.Address = '100E, 40N'
PersonAddress.address()
# 100E, 40N
PersonInformation.age()
PersonAddress.age()
# 17
# 17
PersonInformation.sex()
PersonAddress.sex()
# male
# male
类的创建流程
# _*_coding:utf-8_*_
# !/usr/bin/env python3
# 类的创建流程:
# 1.检测类中是否有明确的__metaclass__属性
# 2.检测父类中是否有存在__metaclass__属性
# 3.检测模块中是否有存在__metaclass__属性
# 4.如果以上都没有则通过内置的type元类来创建这个类对象
# 元类的运用场景:
# 1.拦截类的创建
# 2.修改类
# 3.返回修改之后的类
# 明确类的__metaclass__属性
# type是内置元类(最大)
# __metaclass__ = 'xxx' # 模块级别的__metaclass__属性
#
#
# class Animal(metaclass='xxx'): # 类中明确方式一
# __metaclass__ = 'xxx' # 类中明确方式二
# pass
#
#
# class Dog(Animal): # 继承Animal的__metaclass__属性
# pass
类的描述
# 类的描述
# 语法:
# class ClassName:
# """
# 类的描述、作用、类的构造函数、类的属性
# """
# def function(self):
# """
# 这个方法的作用效果,参数以及参数的含义、类型、默认值,返回值的含义以及类型
# """
# 调用类的描述文档的方法:help(ClassName)
class MathCompulsoryOne:
"""
这个类的主要作用是获取用户输入的方程的参数并计算给定x时的f(x)值
"""
@classmethod
def unary_function(cls, k, x, b):
"""
这个方法主要是计算给定的一元一次方程的值
:param k:斜率,float类型
:param x:x的取值,float类型
:param b:截距,float类型
:return:没有返回值
"""
if b < 0:
print('一元一次函数公式是f(x) = {0}x{2},当x = {1},f(x) = {3}'.format(k, x, b, k * x + b))
else:
print('一元一次函数公式是f(x) = {0}x+{2},当x = {1},f(x) = {3}'.format(k, x, b, k * x + b))
help(MathCompulsoryOne)
# Help on class MathCompulsoryOne in module __main__:
#
# class MathCompulsoryOne(builtins.object)
# | 这个类的主要作用是获取用户输入的方程的参数并计算给定x时的f(x)值
# |
# | Class methods defined here:
# |
# | unary_function(k, x, b) from builtins.type
# | 这个方法主要是计算给定的一元一次方程的值
# | :param k:斜率,float类型
# | :param x:x的取值,float类型
# | :param b:截距,float类型
# | :return:没有返回值
# |
# | ----------------------------------------------------------------------
# | Data descriptors defined here:
# |
# | __dict__
# | dictionary for instance variables (if defined)
# |
# | __weakref__
# | list of weak references to the object (if defined)
注释文档的生成
# _*_coding:utf-8_*_
# !/usr/bin/env python3
# 生成项目文档
# 方式一:cmd中使用内置模块pydoc
# 查看文档描述:python3 -m pydoc 模块名称(不需要后缀)
# 启动本地服务,浏览文档:python3 -m pydoc -p 端口地址
# 生成指定模块html文档:python3 -m pydoc -w 模块名称
# 方式二:使用第三方库:Sphinx, epydoc, doxygen
属性补充
私有化属性概念
# _*_coding:utf-8_*_
# !/usr/bin/env python3
# 私有化属性
# 概念:使得属性只能在某个固定的范围内访问
# 意义:保护数据安全
# 形式:
# attribute
# _attribute
# __attribute
# 注意:python并没有真正的私有化支持,当时可以通过下划线完成伪私有的效果;类属性和实例属性遵循相同的原则
公有属性的访问权限
# _*_coding:utf-8_*_
# !/usr/bin/env python3
# 公有属性的访问权限
# 能够访问的方式:
# 类内部
# 子类内部
# 模块内其他位置:
# 类访问:父类和派生类
# 实例访问:父类实例和派生实例
# 跨模块访问:使用import 模块名 / from 模块名 import *访问
class Currency:
Rmb = "¥"
Dollar = "$"
@classmethod
def output_rmb(cls):
print(cls.Rmb)
def output_dollar(self):
print(self.Dollar)
# 类的内部访问
Currency.output_rmb()
# ¥
# 子类内部访问
class Money(Currency):
def output_currency(self):
print(self.__Rmb)
print(self.__Dollar)
Money.output_currency()
# ¥
# $
# 实例访问
dollar = Currency()
dollar.output_dollar()
# $
# 派生实例访问
rmb = Money()
rmb.output_rmb()
# ¥
# 模块内其他位置访问
print(Currency.Rmb)
print(Money.Dollar)
# ¥
# $
# 跨模块访问
# Definition_Class.py
# num = 10
#
#
# class UserInformation:
# name = 'David'
# age = 19
import Definition_Class
print(Definition_Class.num)
print(Definition_Class.UserInformation.name)
# 10
# David
受保护的属性(_attribute)访问权限
# _*_coding:utf-8_*_
# !/usr/bin/env python3
# 受保护的属性(_attribute)访问权限
# 访问方式:
# 类内部 可以
# 子类内部 可以
# 模块内其他位置:
# 类访问:父类和派生类 可以,但pycharm有警告
# 实例访问:父类实例和派生实例 可以,但pycharm有警告
# 跨模块访问:
# 使用import 模块名 可以,但pycharm有警告
# from 模块名 import *访问 直接访问会报错:AttributeError: module 'Definition_Class' has no
# attribute '_num',如果一定要使用该方法访问,需在原模块首添加__all__ = [attribute]
class Currency:
_Rmb = "¥"
_Dollar = "$"
@classmethod
def output_rmb(cls):
print(cls._Rmb)
def output_dollar(self):
print(self._Dollar)
# 类的内部访问
Currency.output_rmb()
# ¥
# 子类内部访问
class Money(Currency):
def output_currency(self):
print(self.__Rmb)
print(self.__Dollar)
Money.output_currency()
# ¥
# $
# 实例访问
dollar = Currency()
dollar.output_dollar()
# $
# 派生实例访问
rmb = Money()
rmb.output_rmb()
# ¥
# 模块内其他位置访问
print(Currency._Rmb)
print(Money._Dollar)
# ¥
# $
# 跨模块访问
# __all__ = ['_num', 'UserInformation']
# Definition_Class.py
# _num = 10
#
#
# class UserInformation:
# _name = 'David'
# _age = 19
from Definition_Class import *
print(_num)
print(UserInformation._name)
# 10
# David
私有属性(__attribute)访问权限
# 私有属性(__attribute)访问权限
# 访问方式:
# 类内部 可以
# 子类内部 不可以
# 模块内其他位置:
# 类访问:父类 可以
# 派生类 不可以
# 实例访问:
# 父类实例 可以
# 派生实例 不可以
# 跨模块访问:
# 使用import 模块名 可以,但pycharm有警告
# from 模块名 import *访问 直接访问会报错:AttributeError: module 'Definition_Class' has no
# attribute 'num',如果一定要使用该方法访问,需在原模块首添加__all__ = [__attribute]
class Currency:
__Rmb = "¥"
__Dollar = "$"
@classmethod
def output_rmb(cls):
print(cls.__Rmb)
def output_dollar(self):
print(self.__Dollar)
# 类的内部访问
Currency.output_rmb()
# ¥
# 实例访问
dollar = Currency()
dollar.output_dollar()
# $
from Definition_Class import *
print(__num)
# 10
私有属性的实现机制
# _*_coding:utf-8_*_
# !/usr/bin/env python3
# 私有属性的实现机制
# 名字重整:解释器自动将__attribute改成另一个名字_ClassName__attribute
# 访问类外私有属性的方式:将想要访问的属性名称改为_ClassName__attribute
# 设置私有属性的目的:
# 防止外界直接访问
# 防止被子类同名称属性覆盖
class Currency:
__Rmb = "¥"
__Dollar = "$"
class Money(Currency):
@classmethod
def output_currency(cls):
print(cls.__dict__)
print(cls._Currency__Rmb)
print(cls._Currency__Dollar)
Money.output_currency()
# {'__module__': '__main__', 'output_currency': <classmethod object at 0x000002185600A400>, '__doc__': None}
# ¥
# $
私有属性的应用场景
# 私有数据的应用场景:保护数据和过滤数据
class PersonInformation:
def __init__(self): # 该方法是给每个有这个类创建的实例(对象)添加默认的属性以及对应的值
self.__age = 18 # 保护数据
def get_age(self, value):
if isinstance(value, int) and 0 < value < 150: # 过滤数据
self.__age = value
else:
print('你输入的数据有误,将使用默认数据18岁')
def output_a