Python面向对象编程

2023-05-16

文章目录

  • 1 作用域
    • 1.1 局部作用域
  • 2 类成员权限
  • 3 是否继承新式类
  • 4 多重继承
  • 5 虚拟子类
  • 6 内省【在运行时确定对象类型的能力】
  • 7 函数参数
  • 8 生成器

1 作用域

1.1 局部作用域

  • 1,当局部变量遮盖全局变量,使用globals()['变量名']来使用全局变量;
  • 2,使用global重新声明全局变量;
  • 3,使用nonlocal让能够给外部作用域(非全局作用域)内的变量赋值
  • 4,如果函数内部需要对行参赋值,以此来影响函数外部的变量,则只能修改参数对象本身;如果参数是不可变,应从函数返回所需要的值【def func(x):return x + 1】;

测试程序:

val1 = 2
val2 = 'a'
def testActionScope():
    val1 = 3
    print(globals()['val1']) # 重新使用全局变量【1】
    global val2 # 重新声明全局变量【2】
    val2 = 'b'

def nestFunc1():
    temp_val = 1
    def nestFunc2():
         nonlocal temp_val # 使用外层嵌套的变量【3】
         temp_val = 200
    nestFunc2()
    return temp_val

if __name__ == '__main__':

    testActionScope()
    print(val2)

    print(nestFunc1())

2 类成员权限

Python中的成员函数和成员变量都是公开的(public),在python中没有类public,private等关键词来修饰成员函数和成员变量。其实,Python并没有真正的私有化支持,但可用下划线得到伪私有。 尽量避免定义以下划线开头的变量!

(1)_xxx "单下划线 " 开始的成员变量叫做保护变量,意思是只有类实例和子类实例能访问到这些变量,需通过类提供的接口进行访问;不能用’from module import *'导入

(2)__xxx 类中的私有变量/方法名 (Python的函数也是对象,所以成员方法称为成员变量也行得通。)," 双下划线 " 开始的是私有成员,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据。

(3)xxx 系统定义名字,前后均有一个“双下划线” 代表python里特殊方法专用的标识,如 init()代表类的构造函数。

特殊方式访问私有函数:

class TestClass():
    def __testFunc1(self):
        print('__testFunc1')

if __name__ == '__main__':
    testClass = TestClass()
    # testClass.__testFunc1()
    testClass._TestClass__testFunc1()

3 是否继承新式类

Python 2.x默认类为经典类,而对属性支持完全者为新式类。

  • 在python2.x中,从object继承得来的类称为新式类(如class A(object))不从object继承得来的类称为经典类(如class A())
  • 新式类跟经典类的差别主要是以下几点:
    • 1, 新式类对象可以直接通过__class__属性获取自身类型:type
    • 2,继承搜索的顺序发生了改变,经典类多继承时属性搜索顺序: 先深入继承树左侧,再返回,开始找右侧(即深度优先搜索);新式类多继承属性搜索顺序: 先水平搜索,然后再向上移动

如果需要创建新式类,则需要使用__metaclass__ = type【紧跟在class语句后
面并缩进】

Python 3.x默认即为新式类,不必显式继承于object类。

@property可以把一个实例方法变成其同名属性,以支持.号访问,它亦可标记设置限制,加以规范,

它以一个函数形式,定义一个属性,与@property实现原理类似,或者就是它的的变异用法。
其原型为:

property(fget=None, fset=None, fdel=None, doc=None)

4 多重继承

如果多个超类以不同的方式实现了同一个方法(即有多个同名方法),必须在class语句中小心排列这些超类,因为位于前面的类的方法将覆盖位于后面的类的方法。【方法解析顺序(MRO)】

class Base:
    def func(self):
        print('Base')

class Derive(Base):
    def func(self):
        print('Derive')

class Derive2(Base):
    def func(self):
        print('Derive2')

class A(Derive, Derive2): # 多重继承时,因为位于前面的类的方法将覆盖位于后面的类的方法
    pass

if __name__ == '__main__':
    # 测多重继承覆盖
    # a = A()
    # a.func()

5 虚拟子类

虚拟子类:将其他的不是从抽象基类派生的类”注册“到抽象基类,让Python解释器将该类作为抽象基类的子类使用。

这样第三方类不需要直接继承自抽象基类。注册的虚拟子类不论是否实现抽象基类中的抽象内容,Python都认为它是抽象基类的子类,调用 issubclass(子类,抽象基类),isinstance (子类对象,抽象基类)都会返回True。

作用:当一个类继承自抽象基类时,该类必须完成抽象基类定义的语义;当一个类注册为虚拟子类时,这种限制则不再有约束力,可以由程序开发人员自己约束自己,因此提供了更好的灵活性与扩展性。

确定需要哪些类以及这些类应包含哪些方法时,尝试像下面这样做。
(1) 将有关问题的描述(程序需要做什么)记录下来,并给所有的名词、动词和形容词加
上标记。
(2) 在名词中找出可能的类。
(3) 在动词中找出可能的方法。
(4) 在形容词中找出可能的属性。
(5) 将找出的方法和属性分配给各个类。

6 内省【在运行时确定对象类型的能力】

如果要确定对象是由什么组成的,应研究模块inspect。这个模块主要供高级用户创建对象浏览器(让用户能够以图形方式浏览Python对象的程序)以及其他需要这种功能的类似程序。

class Base:
    def func(self):
        print('Base')

class Derive(Base):
    def func(self):
        print('Derive')

class Derive2(Base):
    def func(self):
        print('Derive2')

class A(Derive, Derive2): # 多重继承时,因为位于前面的类的方法将覆盖位于后面的类的方法
    pass
    
if __name__ == '__main__':
    a = A()
    print(hasattr(a, 'func2'))
    print(getattr(a, 'func2', None))
    setattr(a, 'func2', 22) # 用于设置属性值,该属性不一定是存在的。
    print(a.func2)
def testKwds2(**kwargs):
    # for k, v in kwargs.items():
    #     print(k)
    #     print(v)
    print(kwargs['gretting'] + kwargs['name'])

if __name__ == '__main__':
    import inspect
    aa = inspect.signature(testKwds2)
    print("inspect.signature(fn)是{0}".format(aa))
    print("inspect.signature(fn)的类型是{0}".format(type(aa)))
    bb = aa.parameters
    print("signature.parameters属性是{0}".format(bb))
    print("signature.parameters属性的类型是{0}".format(type(bb)))
    for cc, dd in bb.items():
        print("mappingproxy.items()返回的值分别是{0},{1}".format(cc, dd))
        print("mappingproxy.items()返回的值类型分别是{0},{1}".format(type(cc), type(dd)))
    ee = dd.kind
    print("parameter.kind属性是{0}".format(ee))
    print("parameter.kind属性类型是{0}".format(type(ee)))
    gg = dd.default
    print("parameter.default属性是{0}".format(gg))
    print("parameter.default属性类型是{0}".format(type(gg)))
    ff = inspect.Parameter.KEYWORD_ONLY
    print("inspect.Parameter.KEYWORD_ONLY属性是{0}".format(ff))
    print("inspect.Parameter.KEYWORD_ONLY属性类型是{0}".format(type(ff)))

7 函数参数

def testArgs(x, y, z):
    print(x + y + z)

def testKwds(greeting='Hello', name='word'):
    print(f'{greeting},{name}')

def testArgs2(*args):
    sum = 0
    for arg in args:
        for a in arg:
            sum += a
    print(sum)

def testKwds2(**kwargs):
    # for k, v in kwargs.items():
    #     print(k)
    #     print(v)
    print(kwargs['gretting'] + kwargs['name'])

if __name__ == '__main__':
    param = (1, 2, 3)
    testArgs(*param)
    params = {'name': 'Sir Robin', 'greeting': 'Well met'}
    testKwds(**params)

    param = (1, 2, 3)
    testArgs2(param)
    params = {'name': 'Sir Robin', 'greeting': 'Well met'}
    testKwds2(name='Sir Robin', gretting='Well met')

8 生成器

def getElemList(): # 测试生成器
    for i in range(1, 10):
        yield i

if __name__ == '__main__':
    print(list(getElemList()))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python面向对象编程 的相关文章

  • Python 3.7 Windows 不支持 dbm.gnu 吗?

    做的时候 import dbm gnu 在适用于 Windows 的标准 Python 3 7 6 64 上 我得到 文件 C Python37 lib dbm gnu py 第 3 行 位于从 gdbm 导入 ModuleNotFound
  • Python 字符串到 SQL IN 参数的列表

    我在 python 中有这个查询 ssim group S1200 S1300 query select WIPMessageCnt from waferdata where recipename in s and equipment an
  • Tkinter - 打开一个窗口并关闭另一个窗口

    我想要一个登录屏幕 当登录成功时 屏幕将关闭并创建一个新屏幕 问题是 当我执行以下代码时 两个屏幕同时打开 如果您有任何改进代码的建议 请提出 from Tkinter import import mysql connector impor
  • Opencv未找到所有轮廓

    我试图找到该图像的轮廓 但是该方法查找轮廓只返回1轮廓 轮廓突出显示image 2 我正在努力寻找all外部轮廓就像这些圆圈 里面有数字 我究竟做错了什么 我可以做什么来实现它 image 1 image 2 以下是我的代码的相关部分 th
  • 如何检查有效的电子邮件地址? [复制]

    这个问题在这里已经有答案了 有没有一种好方法可以使用正则表达式检查表单输入以确保它是正确样式的电子邮件地址 从昨晚开始就一直在搜索 如果它是子域名电子邮件地址 那么每个回答过人们有关该主题的问题的人似乎也有问题 无关紧要 即使您可以验证电子
  • 将逻辑回归从 R 迁移到 rpy2

    我正在尝试使用 ryp2 进行逻辑回归 我设法执行它 但不知道如何从结果中提取系数和 p 值 我不想在屏幕上打印这些值 而是创建一个函数来独立使用它们 import rpy2 robjects as ro mydata ro r data
  • 配置解析器和带 % 的字符串

    愚蠢的问题 当然 简单的答案 我正在使用 configparser 从文件中读取一些字符串 当字符串具有 符号 例如 时 它会抱怨 ConfigParser InterpolationSyntaxError 后必须跟 或 找到 有人熟悉这个
  • PyDev 无法再调试

    我正在使用 eclipse 4 2 1 和 pydev 2 7 1 以前是 2 6 0 一切都工作正常 直到调试器突然停止工作 它打印 pydev debugger 开始 然后根本不运行程序 而是挂起 根据我在其他问题报告中找到的一些信息
  • 由于 __init__ 构造函数而产生的 Pytest 集合警告

    我一直在使用 Pytest 和 Selenium Web 驱动程序自学测试自动化 我所有的测试函数都在一个名为测试网络 py 它位于名为的目录中tests 我将所有函数分开 并将它们放在一个名为的单独目录中的自己的文件中测试用例 例如 这就
  • 在 python 中读取具有恶意字节 0xc0 的文件,导致 utf-8 和 ascii 出错

    尝试将制表符分隔的文件读入 pandas 数据帧 gt gt gt df pd read table fn na filter False error bad lines False 它会出错 如下所示 b Skipping line 58
  • 如何使用 cron 作业运行 python 文件

    您好 我创建了一个 python 文件 例如file example py 该文件将输出 sensex 值 假设该文件在linux系统上的路径为 Desktop downloads file example py 我通常会运行该文件pyth
  • Pandas 随机样本删除

    我知道DataFrame sample 但是我怎样才能做到这一点并从数据集中删除样本呢 注意 据我所知 这与替换采样无关 例如这里是精华我想要实现的目标 这实际上不起作用 len df 1000 df subset df sample 30
  • 在Python中获取目录基名的优雅方法?

    我有几个脚本将目录名称作为输入 并且我的程序在这些目录中创建文件 有时我想获取给程序的目录的基本名称 并用它在目录中创建各种文件 例如 directory name given by user via command line output
  • 从 ipywidgets FileUpload 访问多个上传文件的内容

    我刚刚学习 ipywidgets 并在 Jupyter Notebook Python 3 中使用它们 基本上 我试图允许用户使用 FileUpload 上传多个文件 然后尝试访问这些文件的内容 以便我可以保存每个文件进入系统 我让它只适用
  • python seaborn:按色调显示 alpha

    在seaborn中 色调为组设置不同的颜色 我可以设置吗alpha取决于组中的JointGrid 或者甚至在单个数据点上 sns set theme jg sns JointGrid data df sns x x y y hue hue
  • Python 类:通过传递值实现单例还是非单例?

    我有一个 Python 3 类 目前是使用 a 定义的单例 singleton装饰器 但有时需要not成为单身人士 问题 是否可以在从类实例化对象时执行类似于传递参数的操作 并且该参数确定该类是否是单例 我试图找到一种替代方法来复制类并使其
  • 从另一个文件执行按钮命令?

    我已经开始开发一个 GUI 系统 在该系统中 我需要从一个文件导入一个函数 以便在按下按钮时在主文件中执行 但每次运行它时 我都会得到 AttributeError partially initialized module Two has
  • Python从更高级别的包导入模块

    这是我的包层次结构 app init py Empty file server py global vars py handlers init py Empty file url1 init py Empty file app1 py ap
  • 从纪元到相对日期的秒数

    我正在处理自纪元以来的日期 并且已经得到了 例如 date 6928727 56235 我想将其转换为另一种相对格式 以便我能够将其转换为与纪元相关的格式 使用 time gmtime date 它返回 year 1970 mon 3 da
  • 从values() 或values_list() 中排除字段

    有没有一种有效的方法从函数中排除字段values or values list e g Videos objects filter id 1 get values 我想从此查询集中排除该字段duration 我知道我可以指定我想要在结果中包

随机推荐