Python灰帽编程——错误异常处理与面向对象

news2024/11/28 1:42:11

文章目录

  • 错误异常处理与面向对象
    • 1. 错误和异常
      • 1.1 基本概念
        • 1.1.1 Python 异常
      • 1.2 检测(捕获)异常
        • 1.2.1 try except 语句
        • 1.2.2 捕获多种异常
        • 1.2.3 捕获所有异常
      • 1.3 处理异常
      • 1.4 特殊场景
        • 1.4.1 with 语句
      • 1.5 脚本完善
    • 2. 内网主机存活检测程序
      • 2.1 scapy 模块
        • 2.1.1 主要功能
        • 2.1.2 scapy 安装
        • 2.1.3 进入scapy 模块
        • 2.1.4 简单使用
      • 2.2 主机存活检测程序
    • 3. 面向对象编程
      • 3.1 类
        • 3.1.1 创建类
        • 3.1.2 \__init__ 方法
      • 3.2 方法
        • 3.2.1 绑定方法
      • 3.3 继承
        • 3.3.1 子类继承
        • 3.3.2 方法重写
        • 3.3.3 多重继承
        • 3.3.4 静态方法和动态方法的区别
      • 3.4 魔法函数
        • 3.4.1 类和实例的内建函数
        • 3.4.2 常用的魔法函数
      • 3.5 私有化

错误异常处理与面向对象

1. 错误和异常

如果遇到了错误(异常),如何去处理?

1.1 基本概念

1.1.1 Python 异常

当程序运行时,因为遇到未知的错误而导致中止运行,便会出现Traceback 消息,打印异常。异常即是一个事件,该事件会在程序执行过程中发生,影响程序的正常执行。一般情况下,在Python 无法正常处理程序时就会发生一个异常。异常是Python 对象,表示一个错误。当Python 脚本发生异常时我们需要响应处理它,否则程序会终止执行

异常描述
SyntaxError语法错误
NameError未声明/初始化对象
IndexError序列中没有此索引
KeyboardInterrupt用户中断执行(Ctrl+C)
EOFError没有内建输入,到达EOF 标记(Ctrl+D) 不适用windows 系统
IOError输入/输出操作失败
ValueError当操作或函数接收到具有正确类型但值不适合的参数, 并且情况不能用更精确的异常,例如 IndexError来描述时将被引发。
TypeError字符串与整数相加时触发。

1.2 检测(捕获)异常

如果一个语句发生了错误或异常,跳过该语句的执行,执行另外的语句。

1.2.1 try except 语句

尝试执行try 语句,如果遇到异常则执行except 语句。两个语句执行执行一个。

语法规则

try:
    pass                # 监控这里的异常
except Exception[, reason]:
    pass                # 异常处理代码

示例:

# 01 - 异常初探.py

try:
    username = input("Please input your name: ")
    print(f"Welcome, {username}")

except:
    print("\nSomething Error!")

1.2.2 捕获多种异常

算命脚本:输入年龄,预测明年的年龄。

可以把多个except 语句连接在一起,处理一个try 块中可能发生的多种异常。

# 02 - 捕获多种异常.py

banner = '''
算命脚本
1. 预测年龄
2. 预测财运
3. 预测姻缘
'''

print(banner)

choice = input("Please input the number: ")
choice = int(choice)

if choice != 1:
    print("好好学习...")
    exit()

try:
    age = input("Please input your age: ")
    print(f"The next year your name: {int(age) + 1}")

except ValueError:
    print("Please input a number!")

except KeyboardInterrupt:
    print("\nCtrl + C")

except:
    print("\nSomething Error!")

1.2.3 捕获所有异常

如果出现的异常没有出现在指定要捕获的异常列表中,程序仍然会中断。可以使用在异常继承的树结构中,BaseException 是在最顶层的,所以使用它可以捕获任意类型的异常。

except BaseException:           # 捕获所有异常,相当于except
    print("\nSomething Error!")

Pyhton 异常树

BaseException                                               所有异常的基类
     |
     |
     +-- SystemExit                                         解释器请求退出
     |
     |
     +-- KeyboardInterrupt                                  用户中断执行(通常是输入^C)
     |
     |
     +-- GeneratorExit                                      生成器调用close();方法时触发的
     |
     |
     +-- Exception                          常规错误的基类,异常都是从基类Exception继承的。
          |
          +-- StopIteration                                 迭代器没有更多的值
          |
          +-- StandardError                                 所有的内建标准异常的基类
          |    +-- BufferError                              缓冲区操作不能执行
          |    +-- ArithmeticError                          所有数值计算错误的基类
          |    |    +-- FloatingPointError                  浮点计算错误
          |    |    +-- OverflowError                       数值运算超出最大限制
          |    |    +-- ZeroDivisionError                   除(或取模)(所有数据类型)
          |    +-- AssertionError                           断言语句失败
          |    +-- AttributeError                           访问未知对象属性
          |    +-- EnvironmentError                         操作系统错误的基类
          |    |    +-- IOError                             输入输出错误
          |    |    +-- OSError                             操作系统错误
          |    |         +-- WindowsError (Windows)         系统调用失败
          |    |         +-- VMSError (VMS)                 系统调用失败
          |    +-- EOFError                                 没有内建输入,到达EOF 标记
          |    +-- ImportError                              导入模块/对象失败
          |    +-- LookupError              无效数据查询的基类,键、值不存在引发的异常
          |    |    +-- IndexError                          索引超出范围
          |    |    +-- KeyError                            字典关键字不存在
          |    +-- MemoryError              内存溢出错误(对于Python 解释器不是致命的)
          |    +-- NameError                未声明/初始化对象 (没有属性)
          |    |    +-- UnboundLocalError                   访问未初始化的本地变量
          |    +-- ReferenceError           弱引用(Weak reference)试图访问已经垃圾回收了的对象
          |    +-- RuntimeError                             一般的运行时错误
          |    |    +-- NotImplementedError                 尚未实现的方法
          |    +-- SyntaxError                              语法错误
          |    |    +-- IndentationError                    缩进错误
          |    |         +-- TabError                       Tab 和空格混用
          |    +-- SystemError                              一般的解释器系统错误
          |    +-- TypeError                                对类型无效的操作
          |    +-- ValueError                               传入无效的参数
          |         +-- UnicodeError                        Unicode 相关的错误
          |              +-- UnicodeDecodeError             Unicode 解码时的错误
          |              +-- UnicodeEncodeError             Unicode 编码时错误
          |              +-- UnicodeTranslateError          Unicode 转换时错误
          |
          +-- Warning                                       警告的基类
               +-- DeprecationWarning                       关于被弃用的特征的警告
               +-- PendingDeprecationWarning                关于特性将会被废弃的警告
               +-- RuntimeWarning              可疑的运行时行为(runtime behavior)的警告
               +-- SyntaxWarning                            可疑的语法的警告
               +-- UserWarning                              用户代码生成的警告
               +-- FutureWarning                            关于构造将来语义会有改变的警告
               +-- ImportWarning               关于模块进口可能出现错误的警告的基类。
               +-- UnicodeWarning                           有关Unicode警告的基类。
               +-- BytesWarning                             有关字节警告相关的基类。

1.3 处理异常

try:                                                # 尝试执行某个语句
    num = int(input("The number:"))
except BaseException:                               # 如果遇到异常,执行的语句
    print("something error!")
else:                                               # 如果没有遇到异常,执行的语句
    print(num)
finally:                                            # 不管是否遇到异常,都要执行的语句。
    print("This is finally")
  • else 子句:在try 范围中没有异常被检测到时,执行else 子句。在else 范围中的任何代码运行前,try 范围中的所有代码必须完全成功。
  • finally 子句:finally 子句是无论异常是否发生,是否捕捉都会执行的一段代码。比如获取用户的输入,写入文件,但是如果在获取数据过程中,发生了异常,就会导致整个脚本结束执行,文件也无法关闭了。为了解决这个问题,可以采用异常处理中的finally 子句,也就是说,无论语句是否正常执行,都需要关闭。
# 03 - 处理异常.py

banner = '''
算命脚本
1. 预测年龄
2. 预测财运
3. 预测姻缘
'''

print(banner)

choice = input("Please input the number: ")
choice = int(choice)

if choice != 1:
    print("好好学习...")
    exit()

try:
    age = input("Please input your age: ")
    age = int(age) 

except ValueError:
    print("Please input a number!")

except KeyboardInterrupt:
    print("\nCtrl + C")

except:
    print("\nSomething Error!")

else:
    print(f"The next year your name: {age + 1}")

finally:
    print("脚本执行结束,祝你好运!")

1.4 特殊场景

1.4.1 with 语句

with 语句是用来简化代码的。比如在将打开文件的操作放在with 语句中,代码块结束后,文件将自动关闭。用来简化文件操作的打开和关闭,其中closed 属性是判断文件是否被关闭的

>>> with open('foo.py') as f:

1.5 脚本完善

from pyfiglet import Figlet
from termcolor import colored, cprint

f = Figlet(font='slant')
print('*' * 75)
print('-' * 75) 
print(f.renderText('WuHu Exception'))
banner = '''
算命脚本
1. 预测年龄
2. 预测财运
3. 预测姻缘
4. 退出脚本
'''
print(banner)
print('-' * 75)
print('*' * 75)

choice = input("请输入你的选项: ")
choice = int(choice)

if choice == 1:
    try:            # 尝试执行某个语句
        age = int(input("Please input your age: "))

    except ValueError:          # 遇到异常执行的语句
        cprint("\nPlease input a number!", "white", "on_red")

    except KeyboardInterrupt:   # 遇到异常执行的语句
        cprint("\nCtrl + C", "white", "on_red")

    except:         # 遇到异常执行的语句
        cprint("\nSomething Error!", "white", "on_red")

    else:           # 如果没有遇到异常,执行的语句   
        cprint(f"\nThe next year your age: {int(age) + 1}", "white", "on_green")

    finally:        # 无论是否遇到异常,都会执行的语句
        cprint("\n脚本执行完毕", "white", "on_green")
elif choice == 4:
    print("欢迎下次光临~")
    exit()
else:
    print("好好学习!")

2. 内网主机存活检测程序

2.1 scapy 模块

与scrapy 有非常大的区别。

scapy 是一个Python 的第三方模块,被称为“网络神器”。scapy 模块能够发送、捕获、分析和铸造网络数据包。

2.1.1 主要功能

image-20230918164616274

2.1.2 scapy 安装

Windows 下安装scapy

python -m pip install scapy

Kali 中自带scapy 环境。

2.1.3 进入scapy 模块

┌──(ajest zh-CN)-[~]
└─$ sudo scapy                     

                     aSPY//YASa       
             apyyyyCY//////////YCa       |
            sY//////YSpcs  scpCY//Pp     | Welcome to Scapy
 ayp ayyyyyyySCP//Pp           syY//C    | Version 2.4.5
 AYAsAYYYYYYYY///Ps              cY//S   |
         pCCCCY//p          cSSps y//Y   | https://github.com/secdev/scapy
         SPPPP///a          pP///AC//Y   |
              A//A            cyP////C   | Have fun!
              p///Ac            sC///a   |
              P////YCpc           A//A   | Craft packets before they craft
       scccccp///pSP///p          p//Y   | you.
      sY/////////y  caa           S//P   |                      -- Socrate
       cayCyayP//Ya              pY/Ya   |
        sY/PsY////YCc          aC//Yp 
         sc  sccaCY//PCypaapyCP//YSs  
                  spCPY//////YPSps    
                       ccaacs         
                                       using IPython 7.22.0
>>>

2.1.4 简单使用

构造数据包

>>> pkt = IP()/TCP()
>>> pkt.show()
###[ IP ]### 
  version   = 4
  ihl       = None
  tos       = 0x0
  len       = None
  id        = 1
  flags     = 
  frag      = 0
  ttl       = 64
  proto     = tcp
  chksum    = None
  src       = 127.0.0.1
  dst       = 127.0.0.1
  \options   \
###[ TCP ]### 
     sport     = ftp_data
     dport     = http
     seq       = 0
     ack       = 0
     dataofs   = None
     reserved  = 0
     flags     = S
     window    = 8192
     chksum    = None
     urgptr    = 0
     options   = ''

>>> pkt = IP(src = "192.168.1.11", dst = "192.168.1.1")/TCP()
>>> pkt.show()
###[ IP ]### 
  version   = 4
  ihl       = None
  tos       = 0x0
  len       = None
  id        = 1
  flags     = 
  frag      = 0
  ttl       = 64
  proto     = tcp
  chksum    = None
  src       = 192.168.1.11
  dst       = 192.168.1.1
  \options   \
###[ TCP ]### 
     sport     = ftp_data
     dport     = http
     seq       = 0
     ack       = 0
     dataofs   = None
     reserved  = 0
     flags     = S
     window    = 8192
     chksum    = None
     urgptr    = 0
     options   = ''

>>>

发送数据包

发送数据包的函数说明
sr(pkt)发送数据包,接收所有返回包
sr1(pkt)发送数据包,接收一个返回包
send(pkt)发送数据包,不等待返回包
srp(pkt)发送2 层数据包,等待回应
sendp(pkt)发送2 层数据包,不等待返回包
>>> res = sr1(pkt)
Begin emission:
Finished sending 1 packets.
.*
Received 2 packets, got 1 answers, remaining 0 packets
>>>

解析:

  • Received 2 packets表示接收了2个包

  • got 1 answers表示响应了1个包

查看返回包

>>> res.show()
###[ IP ]### 
  version   = 4
  ihl       = 5
  tos       = 0x0
  len       = 44
  id        = 13990
  flags     = 
  frag      = 0
  ttl       = 255
  proto     = tcp
  chksum    = 0x46a4
  src       = 10.9.21.1
  dst       = 10.9.21.111
  \options   \
###[ TCP ]### 
     sport     = http
     dport     = ftp_data
     seq       = 1510518667
     ack       = 1
     dataofs   = 6
     reserved  = 0
     flags     = SA
     window    = 65535
     chksum    = 0x4f9c
     urgptr    = 0
     options   = [('MSS', 1460)]
###[ Padding ]### 
        load      = '\x00\x00'

>>>

2.2 主机存活检测程序

# 04 - 内网主机存活检测程序.py

from scapy.all import *
from scapy.layers.inet import *
from termcolor import colored, cprint

import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)	



network = "192.168.188."

for host in range(1, 20):
    ip = f"{network}{host}"
    # print(f"[-] Trying: {ip}")
	
    # 创建数据包
    pkt = IP(src = "192.168.188.185", dst = ip)/ICMP()
    # 发送数据包
    res = sr1(pkt, timeout = 0.2, verbose = False)
    
    if res and res.type == 0:
        print(colored(f"\n{ip} is ALIVE!","green"))
    else:
        print(f"\n{ip} is NOT ALIVE!",end= "")

解析:

  • res = sr1(pkt, timeout = 0.2, verbose = False)sr1() 函数将发送数据包并等待响应,然后返回第一个收到的响应数据包。如果在指定的超时时间内没有收到响应,则返回 None。并且禁用了详细输出。

    • timeout = 0.2:设置的超时时间为0.2
    • verbose = False:禁用了详细输出
  • logging:屏蔽信息模块。

  • logging.getLogger("scapy.runtime").setLevel(logging.ERROR):在scapy运行期间,只有ERROR才显示输出其他都不输出。

3. 面向对象编程

3.1 类

类是一类事物的统称,比如学生。对象就是类的实例化。

类有属性(变量),比如学生的姓名、性别、年龄、成绩等,也就是编程里面的变量。

类有方法(函数),比如学生的上课、下课等,也就是编程里面的函数。

3.1.1 创建类

类是一种数据结构,我们可以用它来定义对象,对象把数据值和行为特性融合在一起。

Python 使用 class 关键字来创建类:通常类名的第一个字母大写,推荐使用驼峰式命名法,单词首字母均大写。类有属性(变量)和方法(动作,函数)组成。

class ClassName(bases):
    'class documentation string'    #'类文档字符串'
    class_suite                     # 类体

3.1.2 _init_ 方法

__init__() 是类的实例(对象)创建后第一个被调用的方法(自动被调用),通常被用来进行对象中属性(变量)的初始化。设置实例的属性可以在实例创建后任意时间进行,但是通常情况下优先在__init__() 方法中实现。

  • 定义类型
  • 实例化对象(创建一个对象)
  • 初始化对象(第一次给对象属性赋值)
# 05 - __init__.py

class Stu():
    def __init__(self, name, sex, age, score):
        self.name = name
        self.sex = sex
        self.age = age
        self.score = score

stu1 = Stu(name = "AJEST", sex = True, age = 24, score = 59.9)

print(f"{stu1.name} 的成绩是{stu1.score}")

解析

  • 在 Python 类中,self 是一个约定俗成的名称也是一个特殊的参数,它表示类的实例(对象)本身。可以使用其他名称代替 self,但强烈建议仍然使用 self,这是因为 self 在Python社区中被广泛接受并被视为最佳实践。在类的方法中,使用 self 参数可以访问该对象的属性和方法。

  • __init__() 方法中,self 参数指向正在创建的对象。通过使用 self 参数,我们可以将传递给 __init__() 方法的参数的值分配给对象的属性,以便在整个类的其他方法中使用。

  • self.name = name 表示将传递给构造函数的 name 参数的值赋给对象的 name 属性。类似地,self.sex = sexself.age = ageself.score = score 将传递的参数值分别赋给对象的 sexagescore 属性。

3.2 方法

3.2.1 绑定方法

方法仅仅是类内部定义的函数,方法只有在其所属的类拥有实例时,才能被调用;任何一个方法定义中的第一个参数都是变量self,它表示调用此方法的实例对象就是自己。

类中的方法,也就是类中定义的函数,这个函数第一个参数永远是self,表示自己。

# 06 - 绑定方法.py

import time

class Stu():
    def __init__(self, name, sex, age, score):
        self.name = name
        self.sex = sex
        self.age = age
        self.score = score

    def getSocre(self):
        print(f"{self.name} 的成绩是{self.score}")

    def goodGoodStudy(self):
        print("好好学习中...")
        time.sleep(10)
        self.score += 0.1


stu1 = Stu(name = "AJEST", sex = True, age = 24, score = 59.9)
stu2 = Stu(name = "HMM", sex = True, age = 24, score = 89.9)

# 调用方法
stu2.getSocre()
stu2.goodGoodStudy()
stu2.getSocre()

解析:

  • getSocre() 方法中,我们使用 self.name 来访问对象的 name 属性。这里的 self 指的就是调用 getSocre() 方法的对象本身。

3.3 继承

3.3.1 子类继承

继承描述了基类(祖先)的属性如何遗传给派生类(子孙),子类可以继承它的基类的任何属性,不管是数据属性还是方法。

# 34 - 子类继承.py

import time

class Kid():
    def __init__(self, name = "", sex = "", age = ""):
        self.name = name
        self.age = age
        self.sex = sex

    def play(self):
        print("玩游戏中...")

class Stu(Kid):
    def __init__(self,name = "", sex = "", age = "", score = ""):
        Kid.__init__(self, name, sex, age)
        self.score = score

    def get_score(self):
        print(f"{self.name} 的成绩是{self.score}")

    def good_good_study(self):
        print("好好学习中...")
        time.sleep(10)
        self.score += 0.1

stu1 = Stu(name = "AJEST", sex = True, age = 24, score = 59.9)
stu2 = Stu(name = "LL", sex = True, age = 25, score = 49.9)
stu3 = Stu(name = "HMM", sex = True, age = 23, score = 99.9)
stu4 = Stu(name = "LH", sex = True, age = 24, score = 79.9)

stu1.play()

3.3.2 方法重写

如果子类中有和父类同名的方法,父类方法将被覆盖;如果需要访问父类的方法,则要调用一个未绑定的父类方法,明确给出子类的实例。

# 08 - 方法重写.py

import time

class Kid():
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age

    def play(self):
        print("玩游戏中...")

class Stu(Kid):
    def __init__(self, name, sex, age, score):
        Kid.__init__(self, name, sex, age)
        self.score = score

    def getSocre(self):
        print(f"{self.name} 的成绩是{self.score}")

    def goodGoodStudy(self):
        print("好好学习中...")
        time.sleep(10)
        self.score += 0.1

    def play(self):
        print("玩王者荣耀中...")
        time.sleep(2)
        self.score -= 10

stu1 = Stu(name = "AJEST", sex = True, age = 24, score = 59.9)
stu2 = Stu(name = "HMM", sex = True, age = 24, score = 89.9)

stu2.getSocre()
stu2.play()
stu2.getSocre()
stu2.goodGoodStudy()
stu2.goodGoodStudy()
stu2.getSocre()
stu2.play()
stu2.getSocre()

说明

  • Kid.__init__(self, name, sex, age) 是在 Stu 类的构造函数中调用了 Kid 类的构造函数来初始化从 Kid 类继承的属性。
  • 在Python中,当一个类继承自另一个类时,子类可以通过调用父类的构造函数来初始化继承的属性。在这个例子中,Stu 类继承自 Kid 类,因此在 Stu 类的构造函数中,我们需要先调用 Kid 类的构造函数来初始化继承的属性。

3.3.3 多重继承

需要注意的是,Python支持单继承和多继承。单继承指一个类只能继承自一个父类,而多继承指一个类可以同时继承自多个父类。在多继承的情况下,子类可以获得多个父类的属性和方法,但需要注意避免出现命名冲突和混淆的情况。

# 09 - 多重继承.py

class A():
    def a():
        print("This is function A!")

class B():
    def b():
        print("This is function B!")

class C(A, B):
    pass

C.a()
C.b()

说明

  • 在Python中,pass 是一个空语句,不执行任何操作。当你在代码中遇到需要写一段代码但又暂时没有实现的情况时,可以使用 pass 来占位,使得代码结构完整而没有语法错误。
# 定义食物类
class Food():
    def __init__(self,name,price):
        self.name = name
        self.price = price

# 定义蔬菜类
class Vegetable(Food):
    def __init__(self,name,price,place):
        Food.__init__(self,name,price)
        self.place = place

# 定义肥料类
class Manure():
    def __init__(self,flag):  
        self.flag = flag      

# 定义西红柿类
class Tomato(Vegetable,Manure):
    def __init__(self, name, price, place,colour,flag):
        Vegetable.__init__(self, name, price, place)
        Manure.__init__(self,flag)
        self.colour = colour
    def wuhu(self):
        print(f"{self.name}价格为{self.price},产地是{self.place},颜色是{self.colour}")
        print(f"添加肥料{self.flag}")


tomato = Tomato("西红柿🍅","23💴","北京","红色🔴","💩")
tomato.wuhu()

3.3.4 静态方法和动态方法的区别

静态方法和动态方法的区别:

  • 静态方法:静态方法是属于类的方法,它与实例无关。它们不需要访问或修改类的实例属性,也没有self参数。静态方法可以被类本身直接调用,而不需要创建类的实例。静态方法通常用于执行与类关联但不依赖于实例的操作,或者在方法内部不需要访问实例属性的情况下。

  • 动态方法:动态方法是属于实例的方法,它需要通过创建类的实例来调用。动态方法的第一个参数通常是self,它代表实例本身。通过这个参数,动态方法可以访问和修改实例的属性。动态方法定义在类的内部,可以通过实例访问,也可以通过类访问。

3.4 魔法函数

3.4.1 类和实例的内建函数

函数作用
issubclass()判断一个类是另一个类的子类或子孙类
isinstance()判定一个对象是否是另一个给定类的实例
hasattr()判断一个对象是否有一个特定的属性
getattr()获得一个对象的属性值
setattr()设置一个对象的属性
delattr()删除一个对象的属性

3.4.2 常用的魔法函数

魔法函数是系统自带的,会在“恰当”的时候自动调用。

# 10 - 魔术方法.py

class Test():
    def __init__(self):
        print("Function __init__ is called!")

    def __str__(self):
        return "Why print(self)?"

    def __call__(self):
        print("Why call me like Function?")

t = Test()

print(t)

t()

解析

  • _init_:该函数会在创建对象的时候调用。
  • _str_:该函数用于返回对象的字符串表示,当尝试将对象转换为字符串时(例如通过 print() 函数或 str() 函数),Python 会调用该方法来获取对象的字符串表示。
  • _call_:当我们使用对象名后面加上一对小括号 () 来调用对象时,Python 会调用该方法。
  • _len_:长度方法,在使用 len() 函数时自动调用,返回对象的长度。
  • _getitem_:索引获取方法,在使用索引访问对象时自动调用,返回对应位置的值。
  • t():使用对象名后面加上一对小括号 () 来调用对象。

3.5 私有化

Python 为类元素(属性和方法)的私有性提供初步的形式,由双下划线开始的属性在运行时被“混淆”,所以直接访问是不允许的。

通过给属性和方法名添加双下划线 __ 来将它们私有化。例如,__score 表示一个私有属性,还可以__method()表示一个私有方法。私有属性和方法只能在类定义中被引用,子类也无法访问

import time

class Stu():
    def __init__(self, name, sex, age, score):
        self.name = name
        self.sex = sex
        self.age = age
        # 定义私有属性
        self.__score = score

    def getSocre(self):
        print(f"{self.name} 的成绩是{self.__score}")

    def goodGoodStudy(self):
        print("好好学习中...")
        time.sleep(10)
        self.__score += 0.1
     
    # 定义私有方法
    def __wuhu(self):
        print("芜湖")

class R(Stu):
    def __init__(self,name,sex,age,score):
        Stu.__init__(self, name, sex, age,score)

    def play(self):
        print("玩🐍")
        print(f"{self.name}的成绩是{self.__score}")        
        
stu1 = Stu("wuhu",True,24,77)

stu1.getSocre()
stu1.goodGoodStudy()
stu1.getSocre()

r = R("haha",True,24,66)
# 调用私有方法
r.__wuhu()
# r.play()

如果Stu的子类访问的话Stu中的私有属性就会抛出一个访问未知对象属性(AttributeError)的异常。

image-20230919141426450

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1023153.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

高并发分布式架构演进之路

淘宝 10 年,高并发分布式架构演进之路 楼仔 2022-04-08987阅读23分钟 大家好,我是楼仔! 之前给自己定了一个学习计划,今年上半年需要完成“高并发”系列文章,这个是该系列的第一篇。 在写“高并发”系列文章之前&a…

23062QTday3

完成文本编辑器的保存工作 //保存文件 void Widget::on_savebtn_clicked() {QString newfileQFileDialog::getSaveFileName(this,"保存文件","./","All(*.*);;Images(*.png *.xpm *.jpg);;Text files(*.txt);;");if(newfile.isNull()){QMessage…

恒合仓库 - 用户管理、用户列表、为用户分配角色

文章目录 用户管理一、用户列表1.1 实体类1.1.1 分页实体类1.1.2 用户信息实体类 1.2 业务实现1.2.1 UserMapper1.2.2 Service层1.2.3 Controller层1.2.4 效果图 二、用户增删改查2.1 添加用户业务实现2.1.1 Mapper2.1.2 Service2.1.3 Controller2.1.4 效果图 2.2 删除用户业务…

十一、MySql的事务(上)

文章目录 一、引入(一)CURD不加控制,会有什么问题?(二)CURD满足什么属性,能解决上述问题? 二、什么是事务?三、事务的特性(一)原子性:…

经典算法-----约瑟夫问题(C语言)

目录 前言 故事背景 约瑟夫问题 环形链表解决 数组解决 前言 今天我们来玩一个有意思的题目,也就是约瑟夫问题,这个问题出自于欧洲中世纪的一个故事,下面我们就去通过编程的方式来解决这个有趣的问题,一起来看看吧&#xff01…

基于Java+SpringBoot+Vue+小程序实现前后端分离二手交易系统

前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 👇🏻…

Vmware通过VMware tools设置共享文件夹

步骤说明: 先安装VMware tools,再设置共享文件夹即可。 写在前面: 刚安装虚拟机时,窗口可能显得太小,这是窗口分辨率没有调整导致的。 点击设置->显示->分辨率调整即可 一、安装VMware tools 1.1 点击虚拟机…

机器人如何有效采摘苹果?

摘要:本文利用动捕数据构建拟人运动模型,对比观察两种苹果采摘模式,并对系统性能进行全面评估,为提高机器人采摘效率提供创新方法。 近期,一项关于苹果采摘机器人的有趣研究—— "Design and evaluation of a rob…

nokov设置教程

1软件安装 设置 屏幕分辨力 缩放问题 软件设置 以管理员身份运行 高DPI缩放行为 系统 软件界面 1 设置路径 全部数据存放于该文件夹下 右下角文件按钮 右键 选择目录 设置完后程序上面显示路径 2 电脑设置ip地址 以太网属性 版本4 查看以太网状态 是否千兆网 网速 …

前序遍历、后序遍历-morris

前序遍历 前序遍历&#xff1a;中 -> 左子树 -> 右子树 非递归的遍历-stack public List<Integer> preorderTraversal(TreeNode root) {List<Integer> res new ArrayList<>();if (null root) {return res;}LinkedList<TreeNode> stack new…

基于 VSC 的 UPFC(统一潮流控制器)研究(Simulink)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

EM算法和VAE的学习笔记

文章目录 摘要EM算法流程EM算法对GMM的参数估计EM算法的证明EM算法的另一种理解VAE参考文献 摘要 这是我学习EM算法&#xff08;Expectation-Maximization Algorithm&#xff09;和VAE&#xff08;Variational Auto-Encoder&#xff09;的学习笔记&#xff0c;首先总结了EM算法…

day5ARM

循环点亮三个led灯 方法1 ------------------led.h---------------- #ifndef __LED_H__ #define __LED_H__#define RCC (*(volatile unsigned int *)0x50000A28) #define GPIOE ((GPIO_t *)0x50006000) #define GPIOF ((GPIO_t *)0x50007000)//结构体封装 typedef struct {vo…

天空飞鸟 数据集

今天要介绍的数据集则是天空飞鸟 数据集&#xff1a; 数据集名称&#xff1a;天空飞鸟 数据集 数据集格式&#xff1a;Pascal VOC格式(不包含分割路径的txt文件和yolo格式的txt文件&#xff0c;仅仅包含jpg图片和对应的xml) 图片数量(jpg文件个数)&#xff1a;以文件包含图片…

alova.js快速入门教程

官网地址&#xff1a;Alova.JS - Lightweight request strategy library | Alova.JS 目录 一、alova 是什么&#xff1f; 二、 快速入门 1、安装依赖 &#xff08;1&#xff09;使用npm方式安装 &#xff08;2&#xff09;使用yarn方式安装 2、在静态 html 中使用 一、al…

CAD for JS:VectorDraw web library 10.1004.1 Crack

VectorDraw web library经过几年的研究&#xff0c;通过互联网展示或工作的可能性并拒绝了各种项目&#xff0c;我们最终得出的结论是&#xff0c;在 javascript 的帮助下&#xff0c;我们将能够在 Microsoft IE 以外的互联网浏览器中通过网络演示矢量图形&#xff08;支持 ocx…

NSSCTF之Misc篇刷题记录(17)

NSSCTF之Misc篇刷题记录&#xff08;17&#xff09; [闽盾杯 2021]DNS协议分析[GFCTF 2021]pikapikapika NSSCTF平台&#xff1a;https://www.nssctf.cn/ PS&#xff1a;所有FLAG改为NSSCTF [闽盾杯 2021]DNS协议分析 数据包提示给得是DNS数据包 直接过滤一下 发现 数据里面存…

分支和远程仓库

分支 查看分支 git branch -v 创建分支 git branch 分支名 切换分支 git checkout 分支名 合并分支 git merge 分支名 把指定的分支合并到当前分支上 查看当前所有远程地址别名&#xff1a; git remote -v 起别名&#xff1a; git remote add 别名 远程地址推送本地分支上的…

【已解决】qt死活不响应鼠标移动到按钮事件

本博文源于笔者正在研究的内容&#xff0c;这个问题大概捣鼓了一个下午&#xff0c;问题是这样子&#xff1a;我有一个按钮&#xff0c;我应用程序运行时&#xff0c;我鼠标放到按钮上&#xff0c;按钮就会被填充图标。怀揣着这样一个想法&#xff0c;我搜啊搜&#xff0c;整啊…

探讨基于IEC61499 的分布式 ISA Batch 控制系统

ISA SP88 是批次过程控制的标准&#xff0c;对应的IEC标准是IEC 61512。该标准中一个重要的部分是配方管理&#xff08;Recipe Management&#xff09;。 所谓配方&#xff0c;是根据批量产品的要求&#xff0c;材料设定加工工艺&#xff0c;加工流程和参数。类似于传统制造业的…