zoukankan      html  css  js  c++  java
  • 面向对象

    特殊成员

    class Foo(object):

        def __init__(self,a1,a2):

            self.a1 = a1

            self.a2 = a2

       

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

            print(11111,args,kwargs)

            return 123

        def __getitem__(self, item):

            print(item)

            return 8

        def __setitem__(self, key, value):

            print(key,value,111111111)

        def __delitem__(self, key):

            print(key)

        def __add__(self, other): 对象相加

            return self.a1 + other.a2

        def __enter__(self):  和下面exit成对出现

            print('1111')

            return 999

        def __exit__(self, exc_type, exc_val, exc_tb):

            print('22222')

    # 1. 类名() 自动执行 __init__

    # obj = Foo(1,2)

    # 2. 对象() 自动执行 __call__

    # ret = obj(6,4,2,k1=456)

    # 3. 对象['xx']  自动执行 __getitem__

    # ret = obj['yu']

    # print(ret)

    # 4. 对象['xx'] = 11  自动执行 __setitem__

    # obj['k1'] = 123

    # 5. del 对象[xx]     自动执行 __delitem__

    # del obj['uuu']

    # 6. 对象+对象         自动执行 __add__

    # obj1 = Foo(1,2)

    # obj2 = Foo(88,99)

    # ret = obj2 + obj1

    # print(ret)

    # 7. with 对象        自动执行 __enter__ / __exit__

    # obj = Foo(1,2)

    # with obj as f:

    #     print(f)

    #     print('内部代码')

    # 8. 真正的构造方法

    # class Foo(object):

    #     def __init__(self, a1, a2):     # 初始化方法

    #         """

    #         为空对象进行数据初始化

    #         :param a1:

    #         :param a2:

    #         """

    #         self.a1 = a1

    #         self.a2 = a2

    #

    #     def __new__(cls, *args, **kwargs): # 构造方法

    #         """

    #         创建一个空对象

    #         :param args:

    #         :param kwargs:

    #         :return:

    #         """

    #         return object.__new__(cls) # Python内部创建一个当前类的对象(初创时内部是空的.).

    #

    # obj1 = Foo(1,2)

    # print(obj1)

    #

    # obj2 = Foo(11,12)

    # print(obj2)

    day25

    特殊方法补充


    # __str__

    class F1(object):

        def __init__(self):
            pass
        def func(self):
            pass

        # 当加了__str__,返回的不再是对象的内存地址,而是str中返回的内容
        def __str__(self):
            return 'F1类'
    obj = F1()

    print(obj)   # <__main__.F1 object at 0x0000018D3F823470> ,返回内存地址
    print(obj)   # F1类 ,当添加了str方法就打印的是返回值


    # __doc__
    class F1(object):
        '''
        
    这里是F1类
        '''
        
    def __init__(self):
            pass
        def func(self):
            pass

    obj = F1()
    print(obj.__doc__) # 打印类最前面的注释,将注释放在下面就打印为None

    # __dict__
    class F1(object):
        '''
        
    这里是F1类
        '''
        
    def __init__(self,name,age):
            self.name = name
            self.age = age
        def func(self):
            pass

    obj = F1('aaa',23)
    print(obj.__dict__)  # {'name': 'aaa', 'age': 23},获取的是一个字典,这样就能获取到对象中的变量值

    # __iter__
    # 列表也是一个类,可以for循环,但们自己写的类就无法循环,也叫不可迭代,添加如下方法可变迭代,使用for循环
    '''
    class F1(object):
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def func(self):
            pass

    obj = F1('aaa',23)
    for item in obj:  # 报错
        print(item) 
    '''

    # 让类变可迭代方法如下
    # 1.在类中定义__iter__方法
    # 2.在iter中返回一个迭代器,或者一个生成器,生成器也是特殊的迭代器

    # 第一种方法,返回迭代器iter()
    '''
    class F1(object):
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def func(self):
            pass
        def __iter__(self):
            return iter([11,22,33])

    obj = F1('aaa',23)
    for item in obj:
        print(item)
    # 11
    # 22
    # 33
    '''
    # 第二种方法,返回生成器
    '''
    class F1(object):
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def func(self):
            pass
        def __iter__(self):
            yield 11
            yield 22
            yield 33

    obj = F1('aaa',23)
    for item in obj:
        print(item)

    # 11
    # 22
    # 33
    '''

    类变量的练习题,列表

    # 第三题:
    """
    class StarkConfig(object):
        list_display = []

        def get_list_display(self):
            self.list_display.insert(0,33)
            return self.list_display

    class RoleConfig(StarkConfig):
        list_display = [11,22]


    s1 = StarkConfig()
    s2 = RoleConfig()

    result1 = s1.get_list_display()
    print(result1) # 33

    result2 = s2.get_list_display()
    print(result2) # 33,11,22
    """

    # 第四题:
    """
    class StarkConfig(object):
        list_display = []

        def get_list_display(self):
            self.list_display.insert(0,33)
            return self.list_display

    class RoleConfig(StarkConfig):
        list_display = [11,22]


    s1 = RoleConfig()
    s2 = RoleConfig()

    result1 = s1.get_list_display()
    print(result1) # 33,11,22

    result2 = s2.get_list_display()
    print(result2)  # 33,33,11,22
    """

    issubclass, type, isinstance  

    # issubclass
    class Foo(object):
        pass
    class Bar(Foo):
        pass

    print(issubclass(Foo,Bar)) # 第一个参数是子类,第二个是父类
    # False
    print(issubclass(Bar,Foo))
    # True

    # type   判断对象是不是由某一个指定类?
    obj = Foo()
    print(type(obj))  # <class '__main__.Foo'>
    if type(obj) == Foo:
        print('obj是Foo的对象')   # obj是Foo的对象

    # 当将一堆对象传给一个函数时,如何判断一个对象是那个类的
    def func(*args):
        foo_count = 0
        bar_count = 0
        for item in args:
            if type(item) == Foo:
                foo_count += 1
            elif type(item) == Bar:
                bar_count += 1
        return foo_count,bar_count

    s1,s2 = func(Foo(),Bar(),Foo())
    print(s1,s2)   # 2 1

    # isinstance   检查第一个参数(对象)是否是第二个参数(类及父类)的实例
    class Foo(object):
        pass
    class Bar(Foo):
        pass
    class Base(Bar):
        pass

    obj = Base()
    print(isinstance(obj,Foo))  # True   # 检查第一个参数(对象)是否是第二个参数(类及父类)的实例
    print(isinstance(obj,Bar))  # True
    print(isinstance(obj,Base)) # True

    obj1 = Bar()
    print(isinstance(obj1,Foo))  # True
    print(isinstance(obj1,Bar))  # True
    print(isinstance(obj1,Base)) # False

    """
    给你一个参数,判断对象是不是由某一个指定类? type                  --> type(obj) == Foo
    给你一个参数,判断对象是不是由某一个指定类或其父类? isinstance    --> instance(obj,Foo)
    """

    方法和函数(不重要)

                  称谓:

                         类,方法

                         外,函数

                  到底方法函数?

                         对象.xxx  --> xxx就是方法

                         类.xxx    --> xxx就是函数

                         xxx       --> xxx就是函数

                  打印查看:

                         function

                         method

                        

                  代码检查:

                         from types import MethodType,FunctionType

                         def check(arg):

                                """

                                检查arg是方法还是函数?

                                :param arg:

                                :return:

                                """

                                if isinstance(arg,MethodType):

                                       print('arg是一个方法')

                                elif isinstance(arg,FunctionType):

                                       print('arg是一个函数')

                                else:

                                       print('不知道是什么')

    反射

    总结:

    v = getattr(obj,"func")  # 根据字符串为参数(第二个参数),去对象(第一个参数)中寻找与之同名的成员。

    好记:

                         getattr # 根据字符串的形式,去对象中找成员。

                         hasattr # 根据字符串的形式,去判断对象中是否有成员。

                         setattr # 根据字符串的形式,动态的设置一个成员(内存)

                         delattr # 根据字符串的形式,动态的删除一个成员(内存)

    具体实例见day25

    问题:你见过那些加()

                         类(),函数(),方法(),对象()是执行__call__方法

    可以通过callable(方法/类,函数,对象)判断

    Day 26

    约束   ***

    class BaseMessage(object):

           def send(self):

                  """

                  必须继承BaseMessage,然后其中必须编写send方法。用于完成具体业务逻辑。

           """

           raise NotImplementedError(".send() 必须被重写.")

           # raise Exception(".send() 必须被重写.")

                                      

           BaseMessage类用于约束,约束其派生类:保证派生类中必须编写send方法,不然执行可能就会报错。

    总结:

    1. 什么是接口以及作用?

    接口时一种数据类型,主要用于约束派生类中必须实现指定的方法。

    Python中不存在,Java和C# 中是存在的。

    2. Python中使用过什么来约束呢?

           - 抽象类+抽象方法,编写上麻烦。

           - 人为主动抛出异常

    3. 约束时,抛出的异常是否可以用其他的?

           不专业:raise Exception(".send() 必须被重写.")

           专业:raise NotImplementedError(".send() 必须被重写."    

    4. 以后看代码,揣摩心思 

    5. 写代码:

    class BaseMessage(object):

    def send(self,x1):

                  """

                  必须继承BaseMessage,然后其中必须编写send方法。用于完成具体业务逻辑。

                  """

                  raise NotImplementedError(".send() 必须被重写.")

    class Email(BaseMessage):

           def send(self,x1):

                  """

                  必须继承BaseMessage,然后其中必须编写send方法。用于完成具体业务逻辑。

                  """

                  print('发送邮件')

    obj = Email()

    obj.send(1)

                               

    6. 应用场景:

           多个类,内部都必须有某些方法时,需要使用基类+异常进行约束。

    自定义异常类         ***

    # 通过自定义异常类,捕获到异常,返回自己想要的信息
    # 知识点:如何自定义异常类
    class MyException(Exception):
        def __init__(self,code,msg):
            self.code = code
            self.msg = msg

    try:
        # 代码块
        raise MyException(1000,'操作异常') 

    except KeyError as obj:
        print(obj,111)
    except MyException as obj:  # 捕获异常
        print(obj,222)
    except Exception as obj: # 当发生了自己没有预料到的异常
        print(obj,333)

    加密 hashlib           *****

    # 示例二
    # 当用通用的md5加密时,可能能在网上破解,因此可以在实例化的时候加盐,达到算出不一样的md5加密

    obj1 = hashlib.md5(b'd4df')
    obj1.update('admin'.encode('utf-8'))
    # 获取密文
    print(obj1.hexdigest()) # ef8470e742484678a6307585a209e5fa

    # 示例三
    # 当在实际使用中,用户输入用户名,保存在数据库中,此时的数据必须加密,当在
    # 验证时,可以将用户输入的密码加密,和数据库中的密文进行对比,
    def md5(pwd):
        obj3 = hashlib.md5(b'd4df')
        obj3.update('admin'.encode('utf-8'))
        return obj3.hexdigest()

    user = input('请输入用户名:')
    pwd = input('请输入密码:')
    if user == 'admin' and md5(pwd) == 'ef8470e742484678a6307585a209e5fa':
        print('登录成功')

    日志logging        ****  

    import logging
    logger = logging.basicConfig(filename='log.txt',
                                 format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
                                 datefmt='%Y-%m-%d %H:%M:%S',
                                 level=30)
    logging.debug('level-10')
    logging.info('level-20')
    logging.warning('level-30')
    logging.error('level-40')
    logging.critical('level-50')

    # 以上是日志对应的级别,config里面为对应的日志内容,可以直接copy
    import traceback
    def func():
        try:
            a = a +1
        except Exception as e:
            # 获取当前错误信息的堆栈信息
            logging.error(traceback.format_exc())
    func()

    多日志文件

    import logging
    # 创建一个操作日志的对象logger(依赖FileHandler)
    file_handler = logging.FileHandler('1.log','a',encoding='utf-8')
    file_handler.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s"))

    logger1 = logging.Logger('s1',level=logging.ERROR)
    logger1.addHandler(file_handler)
    logger1.error('将错误信息写入1.log文件中')


    # 再创建一个操作日志的对象logger(依赖FileHandler)
    file_handler1 = logging.FileHandler('2.log','a',encoding='utf-8')
    file_handler1.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s"))

    logger2 = logging.Logger('s2',level=logging.ERROR)
    logger2.addHandler(file_handler1)
    logger2.error('将错误信息写入2.log文件中')

    argparse模块

    argsparse是python的命令行解析的标准模块

    # ##分析传入参数
    parser = ArgumentParser(description='manual to this script')
    parser.add_argument('--case', type=str, default='')
    parser.add_argument('--service', type=str, default='')
    args = parser.parse_args()

    Cmd下

    python main.py --case projects.service.verifyservice

    打印args结果为

    Namespace(case='projects.service.verifyservice', service='')

    可选参数

    为了在命令行中避免上述位置参数的bug(容易忘了顺序),可以使用可选参数,这个有点像关键词传参,但是需要在关键词前面加(以上实例就是可选参数,如果去掉—就是位置参数需要一一对应)

    默认值

    add_argument中有一个default参数。有的时候需要对某个参数设置默认值,即如果命令行中没有传入该参数的值,程序使用默认值。如果命令行传入该参数,则程序使用传入的值

    必需参数

    add_argument有一个required参数可以设置该参数是否必需。required=True

    parser.add_argument('--name', type=str, required=True, default='', help='名')

    configparser模块简介

    以下是 configparser 模块的基本方法:

    • 读取配置文件
    • defaults() 返回包含实例范围默认值的字典
    • read(filename) 直接读取ini文件内容
    • sections() 获取所有的 section,以列表的形式返回
    • options(section) 获取指定 section 的所有的 option
    • items(section) 获取指定 section 所有的键值对
    • get(section, option) 获取指定 section 中 option 的值
    • getint(section, option) 获取指定 section 中 option 的值,以 int 类型返回
    • getfloat(section, option) 获取指定 section 中 option 的值,以 float 类型返回
    • getboolean(section, option) 获取指定section 中 option 的值,以 boolean类型返回
    • 写入配置文件
    • add_section(section) 添加指定的新的 section
    • has_section(section) 判断是否存在指定的 section
    • set(section, option, value) 设置指定 section 中 option 的值
    • remove_section(section) 删除指定 section
    • remove_option(section, option) 删除指定 section 中的 option
    • write(fileobject) 将内容写入配置文件

    https://blog.csdn.net/atlansi/article/details/83243478

    importlib模块

    Python中动态导入对象importlib.import_module()的使用

    一个函数运行需要根据不同项目的配置,动态导入对应的配置文件运行。

    from importlib import import_module

    or

    import importlib

    im = importlib.import_module()

  • 相关阅读:
    lambda表达式
    netstat
    【makfile | 资源】网址链接
    【makefile】 $@ $^ %< 的使用

    【顺序容器 || 09】
    标准IO库
    我使出这“三板斧”(分段锁、哈希锁、弱引用锁)灭霸跑了......
    JAVA 线上故障排查完整套路,从 CPU、磁盘、内存、网络、GC 一条龙!
    一条 SQL 引发的事故,同事直接被开除!
  • 原文地址:https://www.cnblogs.com/Aline2/p/13375534.html
Copyright © 2011-2022 走看看