首页 > 编程语言 >python基础-面向对象3

python基础-面向对象3

时间:2023-10-20 16:55:57浏览次数:36  
标签:__ python self 基础 面向对象 mro pass print class

目录

1. 继承补充

  • 继承存在的意义: 将公共的方法提取到父类,有利于增加代码重用性
  • 继承的编写方式:
# 继承
class Base(object):
    pass

class Foo(Base):
    pass


# 多继承
class Base(object):
    pass
class Bar(object):
    pass
class Foo(Base,Bar):
    pass
  • 调用类中的成员时遵循:
    • 优先在自己所在的类去找,没有则取父类中去找
    • 如果类存在多继承(多个父类),则先找左边再找右边

1.1 mro 和 c3算法

如果类中存在继承关系,可以通类.mro() 获取当前类的继承关系(找成员的顺序)

  • C3算法广度优先

示例1:

cf0bde428f93c863b91280a58bcef73.png

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

print(A.mro())   # [<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class 'object'>]
print(A.__mro__) # (<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class 'object'>)
# C3算法
# mro(A) 代表想要推算A的继承关系
mro(A) = [A] + merge(mro(B),mor(C),[B,C])
mro(A) = [A] + merge([B],[C],[B,C])  # 先推算[B] 是否是 [C],[B,C] 的子类(依次比对),不是则提取出来,是则跳过(保留),继续推算
mro(A) = [A] + [B,C]
mro(A) = [A,B,C]

示例2:

14c8f00e749ef09e74395fa25336125.png

class D(object): pass
class C(D): pass
class B(object): pass
class A(B,C): pass

print(A.mro())  # [<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class 'object'>]
print(C.mro())  # [<class '__main__.C'>, <class '__main__.D'>, <class 'object'>]
# C3算法
mro(A) = [A] + merge(mro(B),mro(C),[B,C])
mro(A) = [A] + merge([B],[C,D],[B,C])
mro(A) = [A] + [B,C,D]
mro(A) = [A,B,C,D]

示例3:

1bad80bc9e7f552b1f7bbb4b54be5bf.png

class D(object): pass
class C(object): pass
class B(D): pass
class A(B,C): pass

print(A.mro()) # [<class '__main__.A'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.C'>, <class 'object'>]
# C3算法
mro(A) = [A] + merge(mro(B),mro(C),[B,C])
mro(A) = [A] + merge([B,D],[C],[B,C])
mro(A) = [A] + [B,D,C]
mro(A) = [A,B,D,C]

示例4:
30f127de2e9382e170e5dac820ea781.png

class D(object): pass
class C(D): pass
class B(D): pass
class A(B,C): pass

print(A.mro()) # [<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class 'object'>]
# C3算法
mro(A) = [A] + merge(mro(B),mro(C),[B,C])
mro(A) = [A] + merge([B,D],[C,D],[B,C])
mro(A) = [A] + [B,C,D]
mro(A) = [A,B,C,D]

示例5:
ae2e4cb2a24964334ba7cb2176c4e4b.png

class M: pass
class N: pass
class E(M): pass
class G: pass
class K: pass
class H(K): pass
class D(G,H): pass
class F(M,N): pass
class P: pass
class C(E,F): pass
class B(D,E): pass
class A(B,C,P): pass

print(A.mro())  # A -> B -> D -> G -> H -> K -> C -> E -> F -> M -> N -> P -> object
# C3算法
mro(A) = [A] + merge(mro(B),mro(C),mro(P),[B,C,P])
--------------------------------------------------
mro(B) = [B] + merge(mro(D),mro(E),[D,E])
  # mro(D) = merge(mro(G),mro(H),[G,H])
    # mro(G) = [G]
    # mro(H) = [H,K]
  # mro(E) = [E,M]
mro(B) = [B] + merge([D,G,H,K],[E,M])
mro(B) = [B,D,G,H,K,E,K]
--------------------------------------------------
mro(C) = [C] + merge(mro(E),mro(F),[E,F])
  # mro(E)= [E,M]
  # mro(F) = [F,M,N]
mro(C) = [C] + merge([E,M],[F,M,N])
mro(C) = [E,F,M,N]
--------------------------------------------------
mro(P) = [P]
--------------------------------------------------
mro(A) = [A] + merge([B,D,G,H,K,E,M],[C,E,F,M,N],[P],[B,C,P])
mro(A) = [A,B,D,G,H,K,C,E,F,M,N,P]

1.2 py2 和 py3继承区别

  • 在python2.2之前,只支持经典类深度优先查找法
    后来,Python想让类默认继承object(其他语言的面向对象基本上也都是默认都继承object),此时发现原来的经典类不能直接集成集成这个功能,有Bug。
    所以,Python决定不再原来的经典类上进行修改了,而是再创建一个新式类来支持这个功能 新式类采用的是广度优先
    python2.2之后经典类和新式类共存。(正式支持是2.3)
    python3中丢弃经典类,只保留新式类。

深度优先和广度优先.png

  • 经典类,不继承object类型
class Foo:
    pass
  • 新式类,直接或间接继承object
class Base(object):
      pass

class Foo(Base):
    pass

2. 内置函数补充

  • classmethodstaticmethodproperty
    以装饰器的形式放在类方法、静态方法、绑定方法

  • callable (__call__):是否可以在后面加括号执行

    • 函数
def func(): pass

print(func)             # <function func at 0x00000227CDF5C1E0>
print(callable(func))   # True
class Foo(): pass

print(callable(Foo))    # True
  • 类中具有__call__方法的对象
class Foo():
    def __init__(self): pass

    def __call__(self, *args, **kwargs): pass


obj = Foo()
print(callable(obj))  # True

  • super:按照mro继承关系向上找成员 (用来处理多重继承问题中直接用类名调用父类方法)
class Top(object):
    def message(self, num):
        print("Top.message", num)


class Base(Top): pass


class Foo(Base):
    def message(self, num):
        print("Foo.message", num)
        super().message(num + 100)  # 与self不同的是super优先去上游去找,Base中没有message方法,继续往上找 -> Top.message(num + 100)


obj = Foo()
obj.message(1)
"""
Foo.message 1
Top.message 101
"""

应用场景:

  • 假如有一个类原来已实现了某些功能,但我们想再其基础上再扩展点功能,可以使用super
class MyDict(dict):
    def get(self, k):
        print('自定义功能')
        return super().get(k)


info = MyDict()
info['name'] = 'xxx'  # 会自动触发__setitem__
info['age'] = 18  # 会自动触发__setitem__
print(info)  # {'name': 'xxx', 'age': 18}

value = info.get('age')
print(value)
"""
print('自定义功能')
通过supper()从dict类返回18
"""
  • type:获取一个对象的类型
v1 = 'hello'
print(type(v1))         # <class 'str'>
print(type(v1) == str)  # True

v2 = ['a','b','c']
print(type(v2))         # <class 'list'>
print(type(v2) == list) # True

class Foo(object): pass
v3 = Foo()
print(type(v3))         # <class '__main__.Foo'>
print(type(v3) == Foo)  # True
  • isinstance:判断对象是否是某个类或其子类的实例
class Top(object): pass
class Base(Top): pass
class Foo(Base): pass

v1 = Foo()
print(isinstance(v1,Foo))   # True,对象v1是Foo类的实例
print(isinstance(v1,Base))  # True,对象v1是Base子类的实例
print(isinstance(v1,Top))   # True,对象v1是Top子类的实例
  • issubclass:判断类是否是某个类的子孙类
class Top(object): pass
class Base(Top): pass
class Foo(Base): pass

print(issubclass(Foo,Base))  # True,Foo是Base的子类
print(issubclass(Foo,Top))   # True,Foo是Top的子类的子类

3. 异常处理

在程序开发中如果遇到一些 不可预知的错误 或 懒得做一些判断时,可以选择用异常处理来做

import requests

url = input("输入url: ")
res = requests.get(url=url)
with open('content.txt',mode='wb') as f:
    f.write(res.content)

上述下载视频的代码在正常情况下可以运行, 但如果遇到网络问题,程序就会报错无法正常运行,此时可以使用异常处理

try:
    代码块
except Exception as e:
    代码块,上述代码出异常待执行
import requests

while True:
    url = input("输入url: ")
    try:
        res = requests.get(url=url)
    except Exception as e:
        print("请求失败,原因{}".format(str(e)))
        continue
    with open('content.txt', mode='wb') as f:
        f.write(res.content)
num1 = input('请输入数字:')
num2 = input('请输入数字:')

try:
    num1 = int(num1)
    num2 = int(num2)
    result = num1 + num2
    print(result)
except Exception as e:
    print("输入错误,{}".format(str(e)))

常见的应用场景:

  • 调用微信的API实现微信消息的推送、微信支付等
  • 支付宝支付、视频播放等
  • 数据库、redis连接和操作
  • 调用第三方的视频播放功能,由第三方的程序出问题导致的错误

异常处理的基本格式:

try:
    # 逻辑代码
except Exception as e:
    # try中的代码如果有异常,则次代码块中的代码会执行
try:
    # 逻辑代码
except Exception as e:
    # try中的代码如果有异常,则次代码块中的代码会执行
finally:
    # try中的代码无论是否报错都会执行,即便在except中执行了return终止函数也会执行,一般用于释放资源
    
"""
try:
    file_object = open('xxx.log')
except Exception as e:
    # 异常处理
finally:
    # try没异常,最后执行finally关闭文件   # try有异常,先执行except中的代码,最后再执行finally中的代码(关闭文件)
    file_object.close() 
"""
import requests
def e():
    url = input("输入url: ")
    try:
        res = requests.get(url=url)
        print('123') # 当捕获到异常此行不会再执行
        flag = 0
    except Exception as e:
        flag = 1
        return "请求失败,原因{}".format(str(e))
    finally:		# 无论是否有异常都会在try之后或except之后、return之前执行
        if flag == 0:
            print('请求成功:')
        print("请求失败")
    print("aaa") # 当捕获到异常此行不会再执行

print(e())

3.1 异常细分

import requests
from requests import exceptions

while True:
    url = input("请输入地址:")
    try:
        res = requests.get(url=url)
        print(res)
    except exceptions.MissingSchema as e:
        print("url架构不存在")
    except exceptions.InvalidSchema as e:
        print("url架构错误")
    except exceptions.InvalidURL as e:
        print("url地址格式错误")
    except exceptions.ConnectionError as e:
        print("网络连接错误")
    except Exception as e:
        print("代码出现异常",e)

如果想对错误进行细分的处理,例如:发生Key错误和发生Value错误分开处理

基本格式:

try:
    # 逻辑代码
    pass

except KeyError as e:
    print("KeyError")
    
except ValueError as e:
    print("ValueError")

except Exception as e:
    print("Exception")

Python内置细分错误:

# 常见异常:
"""
AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
IOError 输入/输出异常;基本上是无法打开文件
ImportError 无法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) ;代码没有正确对齐
IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问n x[5]
KeyError 试图访问字典里不存在的键 inf['xx']
KeyboardInterrupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError 传入对象类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
导致你以为正在访问它
ValueError 传入一个调用者不期望的值,即使值的类型是正确的
"""


# 更多异常:
"""
ArithmeticError
AssertionError
AttributeError
BaseException
BufferError
BytesWarning
DeprecationWarning
EnvironmentError
EOFError
Exception
FloatingPointError
FutureWarning
GeneratorExit
ImportError
ImportWarning
IndentationError
IndexError
IOError
KeyboardInterrupt
KeyError
LookupError
MemoryError
NameError
NotImplementedError
OSError
OverflowError
PendingDeprecationWarning
ReferenceError
RuntimeError
RuntimeWarning
StandardError
StopIteration
SyntaxError
SyntaxWarning
SystemError
SystemExit
TabError
TypeError
UnboundLocalError
UnicodeDecodeError
UnicodeEncodeError
UnicodeError
UnicodeTranslateError
UnicodeWarning
UserWarning
ValueError
Warning
ZeroDivisionError
"""

3.2 自定义异常和抛出异常

以上都是Python内置的异常,只有遇到特定的错误之后才会抛出相应的异常

在开发中也可以自定义异常:

class MyException(Exception): pass

对于自定义异常如果想要触发,需要使用 rasise MyExcetion() 实现

class MyException(Exception):
    def __init__(self, msg, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.msg = msg


try:
    # ...
    raise MyException("xxx失败了")  # 当遇到raise MyException("xxx失败了"),程序会立即报错,交给MyException
except MyException as e:
    print("MyException被触发了", e.msg)
except Exception as e:
    print('Exception被触发了', e)
class MyException(Exception):
    title = "请求错误"

try:
    # ...
    raise MyException()
except MyException as e:
    print("MyException被触发了",e.title)
except Exception as e:
    print('Exception被触发了',e)

应用场景:

  1. 协同开发,B同事用A同事写的方法
  • A同事定义了一个函数
import re
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr

class EmailValidError(Exception):
    title = "邮箱格式错误"

class ContenRequireError(Exception):
    title = "邮箱内容错误"

def send_email(email,content):
    if not re.match("\w.+qq.com",email):
        raise EmailValidError()
    if len(content) == 0:
        raise ContenRequireError()

    """邮件内容配置"""
    # 邮件文本
    msg = MIMEText(content,'html','utf-8')
    # 邮件上显示的发件人
    msg['From'] = formataddr(['邵冲','[email protected]'])
    # 邮件上显示的主题
    msg['Subject'] = '测试邮件'

    """发送邮件"""
    server = smtplib.SMTP_SSL('smtp.163.com')
    server.login('[email protected]','QDZJCKKEJRWNPIAK')
    server.sendmail('[email protected]',email,msg.as_string()) # 我的邮箱,要发送的邮箱(引入参数),邮件的内容
    server.quit()
  • B同事调用A的函数
def execute():
    try:
        send_email('[email protected]','测试邮件')
    except EmailValidError as e:
        print(e.title)
    except ContenRequireError as e:
        print(e.title)
    except Exception as e:
        print(e)

execute()
  1. 定义好框架,遇到不同错误触发不同异常
import requests
from requests import exceptions

while True:
    url = input("请输入地址:")
    try:
        res = requests.get(url=url)
        print(res)
    except exceptions.MissingSchema as e:
        print("url架构不存在")
    except exceptions.InvalidSchema as e:
        print("url架构错误")
    except exceptions.InvalidURL as e:
        print("url地址格式错误")
    except exceptions.ConnectionError as e:
        print("网络连接错误")
    except Exception as e:
        print("代码出现异常",e)
    1. 按照规定去触发指定异常,每种异常都具备特殊的含义 image-20220416204342753.png

3.3 finally和else

3.3.1 特殊的finally

try:
    # 逻辑代码
except Exception as e:
    # try中的代码如果有异常,则次代码块中的代码会执行
finally:
    # try中的代码无论是否报错都会执行,一般用于释放资源
print('end')
  • 如果在函数中定义了 tryexcept,不管里面是否出现了 returnfinally 一定会在 return之前执行
def func(name):
    try:
        return name
    except Exception as e:
        pass
    finally:
        print('123')

func('小明')
  • 不建议在finally里面写return语句,这样会使其他地方的return语句都失效
def func(name):
    try:
        return name
    except Exception as e:
        pass
    finally:
        return '123'


v1 = func('小明')
print(v1) # 123 

3.3.2 else

  • else存在的意义在于判断try语句有没有异常,有异常则else不会执行 。
try:
    print('执行sql')
    错误的sql
except Exception as e:
    print('回滚')
else:
    print('提交sql')

3.3.3 traceback

  • 异常回溯
import traceback

try:
   a=1/0
except:
    traceback.print_exc()
finally:
    print("有无异常都执行一次")

3.4 异常练习题

  1. 实现捕获程序中的异常
class IterRange(object):
    def __init__(self, num):
        self.num = num
        self.counter = -1

    def __iter__(self):
        return self

    def __next__(self):
        self.counter += 1
        if self.counter == self.num:
            raise StopIteration()
        return self.counter


obj = IterRange(20)

# 补充代码
while True:
    try:
        ele = next(obj)
    except StopIteration as e:
        print("数据捕获完毕")
        break
    print(ele)
  1. 实现捕获程序中的异常
class IterRange(object):
    def __init__(self,num):
        self.num = num
        self.counter = -1
    def __iter__(self):
        return self
    def __next__(self):
        self.counter += 1
        if self.counter == self.num:
            raise StopIteration()
        return self.counter

class Xrange(object):
    def __init__(self,max_num):
        self.max_num = max_num
    def __iter__(self):
        return IterRange(self.max_num)

data_object = Xrange(100)           # 实例化出一个可迭代对象
obj_iter = data_object.__iter__()

# 补充代码
while True:
    try:
        ele = next(obj_iter)
    except StopIteration as e:
        print("数据捕获完毕")
        break

    print(ele)
  1. 实现捕获程序中的错误
def func():
    yield 1
    yield 2
    yield 3

gen = func()

# 补充代码
while True:
    try:
       ele = next(gen)
    except StopIteration as e:
        print("数据捕获完毕")
        break
    print(ele)
  1. 实现捕获程序中的错误
# invalid literal for int() with base 10: '小明'
try:
    name = int("小明")
except ValueError as e:
    print(e)
# list index out of range
data = [11,22,33,44,55]

try:
    data[1000]
except IndexError as e:
    print(e)
# KeyError: 'xxx'
data = {'k1': 123, 'k2': 456}
try:
    data['xxx']
except KeyError as e:
    print('没有Key:',e)
  1. 分析代码写结果
class MyDict(dict):
    def __getitem__(self, item):
        try:
            return super().__getitem__(item)
        except KeyError as e:
            return None

info = MyDict()
info['name'] = '小明'
info['age'] = 18

print(info['name'])  # 小明   info['name'] -> __getitem__
print(info['email']) # None  info['name'] -> __getitem__
  1. 看代码写结果
def func():
    print('666')
    return "成功"

def run(handler):
    try:
        num = handler()
        print(num)
        return func()
    except Exception as e:
        return "错误"
    finally:
        print("End")
    print("结束")

res = run(lambda :123)  # run传入了一个匿名函数的返回值 (lambda :123 匿名函数返回值123
print(res)
"""
return 123
print('666')
print("End")
return "成功"
"""

4. 反射

反射的关键特点是以字符串的形式操作对象,它提供了动态性,允许你在运行时基于条件和变量来访问对象的属性和方法。

class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def show(self):
        print("姓名:{}\t年龄:{}".format(self.name, self.age))


user_obj = Person('小明', 18)

# 对象.成员的格式去获取数据
print(user_obj.name, user_obj.age)
user_obj.show()

# 对象.成员的格式去设置数据
user_obj.name = '小红'

当你使用 method = user_obj.name 这种方式时,它是静态的,方法名称是固定的,不具备动态性,只能访问特定方法
而使用 method = getattr(obj, "name") 这种方式是反射,你可以通过字符串变量来动态选择要调用的方法,这使得代码更加灵活和通用。

class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def show(self):
        print("姓名:{}\t年龄:{}".format(self.name, self.age))


user_obj = Person('小明', 18)

# getattr 获取成员
getattr(user_obj, 'name')
getattr(user_obj, 'age')
getattr(user_obj, 'show')()  # user_obj.show()
method = getattr(user_obj, 'show')
method()

# setattr 设置成员
setattr(user_obj, 'name', '小红')  # user_obj.name = '小红'
getattr(user_obj, 'show')()  # user_obj.show()

Python中提供了4个内置函数来提供反射:

  • getattr:去对象中获取成员
v1 = getattr(对象,"成员名称")   # 如果成员不存在则返回None
v2 = getattr(对象,"成员名称", "不存在时的默认值")
  • setattr:去对象中设置成员
setattr(对象,"成员名称",值)
  • hasattr:判断对象中是否包含成员
v1 = hasattr(对象,"成员名称")  # True/False
  • delattr:删除对象中的成员
delattr(对象,"成员名称")
delattr(user_obj,"name") # del user_obj.name

案例:

class Account(object):
    def login(self):
        print("请注册")

    def register(self):
        print("请注册")

    def index(self):
        print("欢迎!")


def run():
    name = input("输入要执行的方法:")  # login、register、index、run、xxx
    account_object = Account()
    method = getattr(account_object, name, None)
    if not method:
        print("没有这个方法")
        return
    method()


run()

4.1 一切皆对象

在Python中:一起皆对象,每个对象的内部都有自己维护的成员

  • 对象是对象
  • 类是对象(平时不这么称呼)
  • 模块是对象(平时不这么称呼)
  • ...

由于反射支持以字符串的形式去对象中操作成员 等价于 对象.成员,所以基于反射,也可以对 模块中的成员进行操作

只要看到 xx.xx 都可以用反射实现

class Person(object):
    title = "嘿嘿"

v1 = Person.title
print(v1)

v2 = getattr(Person,'title')
print(v2)
import re

email = re.match('\w.+@\w.+\.com','[email protected]')
# print(email.group())
get_email = getattr(email,'group')
print(get_email())


func = getattr(re,'match')
get_email2 = func('\w.+@\w.+\.com','[email protected]')
print(get_email2.group())

4.2 import_module + 反射

在Python中导入一个模块可以通过import 导入,也可以通过字符串的形式导入

  • 注意:import_module最大只能导入模块级别,无法导入模块内的成员

  • 示例1:

# 导入模块
# import random as m
# print(m.randint(1,100))

from importlib import import_module

m = import_module('random')
print(m.randint(1,100))
  • 示例2:
# 导入模块 exceptions
# from requests import exceptions as m

from importlib import import_module

m = import_module('requests.exceptions')
  • 示例3:
# 导入模块exceptions,获取exceptions中的InvalidURL类
# from requests.exceptions import InvalidURL as m

from importlib import import_module

# 错误方式
# m = import_module('requests.exceptions.InvalidURL')  # 报错,import_module 只能导入到模块级别

# 正确方式
m = import_module('requests.exceptions')  # 先导入模块,m 代表导入成功后模块的名字
cls = m.InvalidURL                        # 再去模块中获取类

在很多项目的源码中都有 import_modulegetattr 配合实现字符串的形式导入模块并获取成员,例如:
反射.zip

from importlib import  import_module

path = "openpyxl.utils.exceptions.InvalidFileException"

module_path,class_name = path.rsplit('.',maxsplit=1) # "openpyxl.utils.exceptions" "InvalidFileException"
module_obj = import_module(module_path)              # "InvalidFileException"
cls = getattr(module_obj,class_name)
print(cls)                                           # <class 'openpyxl.utils.exceptions.InvalidFileException'>

5. 练习题

  1. super的作用
根据类继承关系向上寻找成员
  1. 看代码写结果
class Foo(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age

    @property
    def message(self):
        return "{}-{}".format(self.name,self.age)

class Bar(Foo):
    def __init__(self,email,*args,**kwargs):
        super().__init__(*args,**kwargs)
        self.email = email

    def total(self):
        data = "{}-{}-{}".format(self.name,self.age,self.email)
        return data

obj1 = Foo("小明",18)
print(obj1.message)   # 小明-18

obj2 = Bar("[email protected]",'root','100')
print(obj2.message)   # root-100
print(obj2.total())   # [email protected]
  1. 看代码写结果
class Foo(object):
    def __call__(self, *args, **kwargs):
        return 666

data_list = [
    "小明",
    dict,
    lambda :123,
    True,
    Foo,
    Foo()
]

for item in data_list:
    if callable(item):
        val = item()
        print(val)
    else:
        print(item)
  1. 如何主动触发一个异常
raise 异常类(...)
  1. 反射的作用
根据字符串的形式操作成员
  1. 看代码写结果
class Person(object):
    title = "北京"

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def show(self):
        msg = "姓名:{}\t年龄:{}".format(self.name, self.age)
        return msg

    @property
    def msg(self):
        return 666

    @staticmethod
    def something():
        return 99


obj = Person('小明', 18)

print(getattr(obj, 'age'))  # 18
print(getattr(obj, 'msg'))  # 666
print(getattr(obj, 'show')())  # 姓名:小明
print(getattr(obj, 'something')())  # 99

标签:__,python,self,基础,面向对象,mro,pass,print,class
From: https://www.cnblogs.com/ican97/p/17777483.html

相关文章

  • python基础-面向对象2
    目录1.成员1.1变量1.2方法1.3属性2.成员修饰符3.对象嵌套4.特殊方法5.练习题1.成员面向对象中的所有成员如下:变量实例变量类变量方法绑定方法类方法静态方法属性1.1变量实例变量,属于对象,每个对象中各自维护自己的数据类变量,属于类,可以被所有对象......
  • python基础-数据类型(字符串-布尔-整数)
    目录1.整数(int)1.1定义1.2独有功能1.3公共功能1.4转换1.5其他1.5.1长整型1.5.2地板除1.5.3其它2.布尔(bool)2.1定义2.2独有功能2.3公共功能2.4转换2.5其他做条件自动转换3.字符串(str)3.1定义3.2独有功能3.2.1练习题3.3公共功能3.4转换3.5其他4.练习题......
  • 实验2— C语言分支与循环基础应用编程
    1.实验任务1源代码1#include<stdio.h>2#include<stdlib.h>3#include<time.h>45#defineN56#defineN13747#defineN246589intmain()10{11intnumber;12inti;1314srand(time(0));1516for......
  • python异常处理else和finally的区别
    Python3错误和异常|菜鸟教程(runoob.com)try/except...elsetry/except 语句还有一个可选的 else 子句,如果使用这个子句,那么必须放在所有的except子句之后。else子句将在try子句没有发生任何异常的时候执行。以下实例在try语句中判断文件是否可以打开,如果打开文......
  • 实验2 C语言分支与循环基础应用编程
    摘要一、实验目的二、实验准备三、实验内容四、实验结论 task1源代码:1#include<stdio.h>2#include<stdlib.h>3#include<time.h>4#defineN55#defineN13746#defineN246578intmain()9{10intnumber;11inti;12srand(time(0));......
  • 函数基础小结
    函数基础小结计算机的组成之编程什么是编程语言什么是编程为什么要编程计算机的五大组成部分CPU内存外存输入设备输出设备32位和64位多核CPU应用程序的启动机械硬盘的工作原理计算机操作系统什么是文件什么是应用程序操作系统有什么用计算机的三大组成硬件操......
  • Mac OS安装Python的pip
    最近牛牛的同学在学习python,但当他使用numpy时出现了报错(。•́︿•̀。)原因为他的python没有numpy这个库(这个故事很典)。然鹅雪上加霜的是,他的电脑是Mac,没有Windows的cmd...牛牛还没碰过苹果电脑,后面通过查找百度发现在苹果里这玩意儿叫Terminal,经历千辛万苦打开Terminal并开始pip后,......
  • 【Python&GIS】基于Python批量合并矢量数据
    ​老样子最近有项目需要将N个矢量文件合并成一个,总不能用ArcGIS一个个导入吧。所以我就想着用Python编个程序实现批量合并矢量。我之前也发了一些关于Python操作矢量数据的文章:【Python&GIS】Python处理矢量数据的基本操作(查询、修改、删除、新建),如果大家感兴趣可以去我的主......
  • Python深浅拷贝
    Python深浅拷贝拷贝/浅拷贝/深拷贝只针对可变数据类型拷贝(赋值)当lt2为lt的拷贝对象时,lt内的可变类型变化,lt2变化;lt内的不可变类型变化,lt2变化简单的赋值lt=[1,2,3]lt2=ltlt.append(4)print(lt)#因为列表是可变类型,所以lt的值变化,lt2的值也会跟着变化print(l......
  • python设置代理ip,动态代理IP有哪些优势?
    在网络爬虫开发中,使用代理IP是非常常见的技巧,Python作为一门强大的编程语言,也提供了很多方法来使用代理IP,下面,我将就如何在Python中使用代理IP进行详细的阐述,并举例说明,需要的朋友可以参考下。1.方法一:使用urllib模块Python中最基础的网络请求是使用urllib模块,我们可以利用它来使......