Python3 面向对象进阶2

目录

  • Classmethod
  • Staticmethod
  • Isinstance
  • Issubclass
  • 反射
    • 概念
    • hasattr
    • getattr
    • setattr
    • delattr
  • 魔法方法
    • 概念
    • __new__
    • __init__
    • __str__
    • __call__
    • __getattr__
    • __setattr__
    • __del__
  • 单例模式
    • 概念
    • 目的
    • 实现方式

Classmethod

  • classmethod是一个装饰器, 用来装饰类内部的方法, 使得该方法绑定给类来使用
  • 对象绑定方法的特殊之处: 由对象调用, 将对象作为第一参数传给该方法
  • 类的绑定方法的特殊之处: 由类来调用, 将类作为第一参数传给该方法

Staticmethod

  • staticmethod是一个装饰器, 用来装饰类内部的方法, 使得该方法既不绑定给对象, 也不绑定给类
# settings.py
USER = 'bigb'
PASSWORD = '123'


import uuid
import settings
import hashlib

class User:
    def __init__(self, username, password):
        self.username = username
        self.password = password

    def admin(self):
        if not self.username == 'bigb' and self.password == '123':
            print('请用管理员账户登录...')
            return

        print('显示管理员功能...')

    @classmethod
    def __from_settings(cls):
        obj = cls(settings.USER, settings.PASSWORD)
        return obj


    @staticmethod
    def creat_id():
        uuid_obj = uuid.uuid4()
        md5 = hashlib.md5()
        md5.update(str(uuid_obj).encode('utf-8'))
        return md5.hexdigest()


obj1 = User._User__from_settings()
obj1.admin()  # 显示管理员功能...


obj2 = User('blake', '123')
obj2.admin()  # 请用管理员账户登录...

print(obj2.creat_id())  # e249b25cdd1963a4949cc99d3ad46ff2

Isinstance

  • isinstance(args1, args2) Python内置函数, 用于判断args1(对象)是否是args2(类)的一个实例
class Foo:
    pass


foo_obj = Foo()

print(isinstance(foo_obj, Foo))  # True

Issubclass

  • issubclass(args1, args2) Python内置函数, 用于判断args1是否是args2的子类
class ParentClass:
    pass


class ChildClass(ParentClass):
    pass


class OtherClass:
    pass


print(issubclass(ChildClass, ParentClass))  # True
print(issubclass(OtherClass, ParentClass))  # False

反射

概念

  • 反射指的是通过字符串对象或类的属性进行操作

hasattr

  • hasattr(o, attrname) 判断 o(类或对象) 中是否有名字叫 attrname (字符串) 这样的一个属性
class Chinese:
    country = 'China'

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


people = Chinese('bigb', '18', 'male')

print('name' in people.__dict__)  # True
print(hasattr(people, 'name'))  # True

getattr

  • getattr(o, attrname, default): 用来获取 o(对象或类) 中名叫 attrname(字符串) 的属性对象, 如果没有则返回默认值default
class Chinese:
    country = 'China'

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

    def say_slogan(self):
        print('One China')


people = Chinese('bigb', '18', 'male')

people.say_slogan()  # One China
getattr(people, 'say_slogan')()  # One China
print(getattr(people, 'country'))  # China
print(getattr(people, 'country1', 'China'))  # China
class Movie:
    def input_cmd(self):
        while True:
            cmd = input('请输入方法名: ')

            if hasattr(self, cmd):
                method = getattr(self, cmd)
                method()

    def upload(self):
        print('电影开始上传...')

    def download(self):
        print('电影开始下载...')


movie_obj = Movie()
movie_obj.input_cmd()

setattr

  • setattr(o, attrname, value) 用来添加或修改 o(对象或类) 的属性: attrname = value
class Chinese:
    country = 'China'

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

    def say_slogan(self):
        print('One China')


people = Chinese('bigb', '18', 'male')

# 修改
setattr(people, 'gender', 'female')
# 添加
setattr(people, 'province', 'Anhui')

print(people.gender)  # female
print(people.province)  # Anhui

delattr

  • delattr(o, attrname) 用来删除 o(对象或类) 中叫做 attrname(字符串) 的属性
class Chinese:
    country = 'China'

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

    def say_slogan(self):
        print('One China')


people = Chinese('bigb', '18', 'male')

# 添加
setattr(people, 'province', 'Anhui')

# 删除
delattr(people, 'province')

print(people.province)  # AttributeError: 'Chinese' object has no attribute 'province'

魔法方法

概念

  • 在类内部定义, 以__开头__结尾的方法的方法都称之为魔法方法, 又称为类的内置方法
  • 魔法方法会在某些条件成立是触发
  • 魔法方法都是object类内定义的方法

__new__

  • 在调用类时自动触发 (return self__init__)
class Foo(object):

    def __new__(cls, *args, **kwargs):
        print('__new__')
        return object.__new__(cls)  # 产生了一个空对象

    def __init__(self):
        print('__init__')


foo_obj = Foo()

'''
__new__
__init__
'''

__init__

  • 在创建完对象后自动触发
  • __init__是实例化对象后触发的第一个方法(接收 __new__ return 的 self)

__str__

  • 在打印对象时自动触发
  • 必须要有一个返回值, 该返回值必须是字符串类型
class Foo(object):

    def __str__(self):
        print('__str__在打印对象时自动触发')
        return '__str__的返回值'


foo_obj = Foo()
print(foo_obj)

'''
__str__在打印对象时自动触发
__str__的返回值
'''

__call__

  • 在对象被调用时自动触发
class Foo(object):

    def __call__(self, *args, **kwargs):
        print('__call__在对象被调用时自动触发')


foo_obj()  # __call__在对象被调用时自动触发

__getattr__

  • 对象.属性时, 没有该属性时候自动触发
class Foo(object):

    # 默认返回None
    def __getattr__(self, item):
        print('__getattr__会在对象.属性,且属性不存在时自动触发')
        return item


foo_obj = Foo()
print(foo_obj.x)

'''
__getattr__会在对象.属性,且属性不存在时自动触发
x
'''

__setattr__

  • 对象.属性=属性值 时自动触发
class Foo(object):

    def __setattr__(self, key, value):
        print('__setattr__在 对象.属性=属性值 时自动触发')
        print(key, value)


foo_obj = Foo()

# 类中有__setattr__ 方法时, 如下操作只触发了__setattr__方法, 并不会给对象添加或修改属性
foo_obj.x = 1

'''
__setattr__在 对象.属性=属性值 时自动触发
x 1
'''

print(foo_obj.x)  # AttributeError: 'Foo' object has no attribute 'x'

__del__

  • 在对象被销毁后自动触发
class Foo(object):

    def __del__(self):
        print('__del__在对象被销毁后自动触发')


foo_obj = Foo()

print('对象被销毁前')
del foo_obj

print('程序最后的代码.')

'''
对象被销毁前
__del__在对象被销毁后自动触发
程序最后的代码
'''
class Myfile(object):
    def __init__(self, file_name, mode='r', encoding='utf-8'):
        self.file_name = file_name
        self.mode = mode
        self.encoding = encoding

    def file_open(self):
        self.f = open(self.file_name, self.mode, encoding=self.encoding)

    def file_read(self):
        data = self.f.read()
        print(f'''
        当前文件: {self.file_name}
        当前文件数据: {data}
        ''')

    def __del__(self):
        self.f.close()
        print('关闭文件成功!')


f = Myfile('test_file.txt')
f.file_open()
f.file_read()

'''
        当前文件: test_file.txt
        当前文件数据: This is the content of test_file.txt
        
关闭文件成功!
'''

单例模式

概念

  • 单例模式指的是某个类在整个系统中只存在一个实例的一种设计模式

目的

  • 减少内存占用
  • 加快运行性能 (只初始化一次)

实现方式

class File(object):
    __instance = None


    # # 方式1, 通过类的绑定方法实现
    # @classmethod
    # def singleton(cls, file_name):
    #     # 当类没有实例时
    #     if not cls.__instance:
    #         # 创建实例
    #         cls.__instance = cls(file_name)
    #     return cls.__instance



    # 方式2, 通过__new__方法实现
    def __new__(cls, *args, **kwargs):
        # 当类没有实例时
        if not cls.__instance:
            # 创建实例
            cls.__instance = object.__new__(cls)
        return cls.__instance

    def __init__(self, file_name, mode='r', encoding='utf-8'):
        self.file_name = file_name
        self.mode = mode
        self.encoding = encoding

    def open(self):
        self.f = open(self.file_name, self.mode, encoding=self.encoding)

    def file_read(self):
        data = self.f.read()
        print(f'''
          当前文件: {self.file_name}
          当前文件数据: {data}
          ''')

    def close(self):
        self.f.close()

# obj1 = File.singleton('test_file.txt')
# obj2 = File.singleton('test_file.txt')
# obj3 = File.singleton('test_file.txt')

obj1 = File('test_file.txt')
obj2 = File('test_file.txt')
obj3 = File('test_file.txt')

print(obj1)
print(obj2)
print(obj3)

'''
<__main__.File object at 0x0000000009F87A58>
<__main__.File object at 0x0000000009F87A58>
<__main__.File object at 0x0000000009F87A58>
'''

你可能感兴趣的:(Python3 面向对象进阶2)