zoukankan      html  css  js  c++  java
  • 类与对象 (01)

    周六又进了趟城, 跟刚从北京过来的小陆学姐, 山大硕士毕业, 然后在四大干了几年, 现在腾讯一部门做战略顾问, 就是很优秀哇. 回顾了一些校园生活, 职场经历, 职场江湖, 还有一些逸闻趣事, 就聊得很嗨. 得出的几个关键结论如下:

    • 企业的文化, 价值观, 战略, 受领导人影响很大

    • 从适普和概率观点来看, 一个人竞争力是, 高学历 + 行业经验, 学历尤为重要

    • 选择领导很重要, 就一个原则: 头脑在线, 人靠谱, 头脑(智商 + 情商) 尤为重要

    • 物以类聚, 人以群分, 不得不承认, 在职场上也是这个自然法则

    • 跳槽其实涨薪水最快的方式, 但前提是, 你在岗期给东家做出了成绩, 同时自己能力不断增强, 且岗位不换

    • 要有职业素养, 最为重要的是, 专业性 + 责任感. 二者同等重要, 这也是凸显了教育培养的重要性

    • 要有底线. 法律和道德的底线, 难免是会涉及到这些敏感区, 需要去挑战试探, 同时也要能搂住底线

    感觉我还是见识不够哇, 我其实很害怕改变, 所有就基本不做商业这块, 只是做些数据, IT 这块, 比较客观, 纯粹, 可以保持住初心的一些事情, 一直在坚持着.

    不扯了...继续温习下类和对象的一些旧知识, 和新的补充.

    围绕 类定义相关的编程模型, 如 Python 特性, 特殊方法使用, 类封装技术, 继承, 内存管理, 设计模式这些

    改变对象的字符串显示

    需求

    改变对象实例的打印或显示输出, 让她们更具有可读性

    方案

    通过重写 _ _ str _ _() 和 _ _ repr _ _ () 方法实现

    class Pair:
        def __init__(self, x, y):
            self.x = x
            self.y = y 
        
        def __repr__(self):
            return f'Pair({self.x}, {self.y})'
        
        def __str__(self):
            return f'{self.x}, {self.y}'
        
    # test 
    p = Pair(1, 2)
    
    print(p)
    p
    
    1, 2
    Pair(1, 2)
    

    __ str __ () 在 print( 实例对象 obj) 时会自动调用. 即将一个对象转为一个字符串, 通常是将对象的一些属性信息给打印出来呀.

    __ repr __ () 方法返回一个实例的代码表示形式, 常用用来重新构造该实例, 内置的 repr() 返回一个字符串, 通常是 repr() 和 eval () 是一个互逆的过程.

    # veal: 字符串转为对象 
    my_str = '{"name": "youge", "age":18}'
    
    str_to_obj = eval(my_str)
    
    print(type(str_to_obj), str_to_obj)
    
    # repr: 对象转字符串 
    obj_to_str = str_to_obj.__repr__()
    
    print(type(obj_to_str), obj_to_str)
    
    <class 'dict'> {'name': 'youge', 'age': 18}
    
    <class 'str'> {'name': 'youge', 'age': 18}
    

    让对象支持上下文管理

    需求

    让对象能使用上下文管理, 即用 with 语句

    方案

    通过实现 __ enter __ () 和 __ exit __ () 方案, 即能用 with 语句.

    跟 for 迭代一样的, for 实现的是 __ iter __ 和 __ next __ 方法

    from socket import socket, AF_INET, SOCK_STREAM 
    from functools import partial 
    
    class LasyConnection: 
        def __init__(self, address, family=AF_INET, type=SOCK_STREAM):
            self.address = address
            self.family = family
            self.type = type 
            self.sock = None 
            
        def __enter__(self):
            if self.sock is not None:
                raise RuntimeError('Already connected')
            # 创建套接字并连接
            self.sock = socket(self.family, self.type)
            self.sock.connect(self.address)
            return self.sock 
            
        def __exit__(self, exc_ty, exc_val, error):
            self.sock.close()
            self.sock = None 
            
    # test 
    con = LasyConnection(('www.baidu.com', 80))
    
    with con as s:
        s.send(b'xxxxxxxx')
        s.send(b'aaaaa')
        resp = b''.join(iter(partial(s.recv, 8888), b''))
    

    编写上下文管理器的主要原理是, 编写的代码会放到 with 语句块中执行.

    • 首先, 当遇到 with 语句时, __ enter __ () 方法会被自动触发. 它的返回值 (如果有) 会被赋值 as 声明的变量. 如 'with open(xxx) as f ' 这个 f 的值即为 __ enter __ () 方法的返回值.
    • 然后, with 语句块中的代码继续开始运行 ... (业务逻辑)
    • 最后, __ exit __ () 方法会被触发, 并进行清理工作.
    # 不需要 调用 close() 的原因, 因为 with 执行结束后会自动清理
    
    with open('xxxx', 'r') as f:
        pass 
    

    不论 with 代码块中发生什么, 上面的控制流都会执行完, 即便发生异常. 事实上, __ exit __ () 方法的第三个参数包含了异常类型, 异常值和追溯信息(如果有). 同时 __ exit __ () 方法能自己决定如何利用这个异常信息, 或者忽略并发返回一个 None. 如果 __ exit __ () 返回 True, 则异常会被清空, with 语句后面的话继续执行.

    上面的这个版本呢, 只能允许一个 with 语句来连接, 一个 socket 显然不行, 于是来改成这样的.

    from socket import socket, AF_INET, SOCK_STREAM 
    
    class LasyConnection: 
        def __init__(self, address, family=AF_INET, type=SOCK_STREAM):
            self.address = address
            self.family = family
            self.type = type 
            self.connections = []
            
        def __enter__(self):
            # 创建套接字并连接
            sock = socket(self.family, self.type)
            sock.connect(self.address)
            # 将每个 socket 都存起来
            self.connections.append(sock)
            return self.sock 
            
        def __exit__(self, exc_ty, exc_val, error):
            self.connections.pop().close()
            
    # test 
    con = LasyConnection(('www.baidu.com', 80))
    
    with con as s1:
        pass 
        with con as s2:
            pass
        # s1 and s2 are independent sockets 
    

    LasyConnection 类就可以看做是一个连接工厂. 在内部, 构造了一个栈 (列表) . 每次 __ enter __ 方法被调用, 就会复制一个新的连接并加入到栈中. 同时 __ exit __ 方法会从栈中 pop 出最后一个 sockets 兄弟给给关闭掉. 它可以允嵌套多个 with 语句创建多连接.

    在管理一些资源文件, 网络连接, 和锁的场景中, 用上下文管理器是非常普遍的. 它们的共同特点是, 必须被手动的关闭或释放来确保程序的正确运行. 如果请求了一个锁, 则必须用后要手动释放, 不然就死锁了. 而通过 实现 __ enter __ 和 __ exit __ 方法 并用 with 语句则可很容易避免这些问题, 因为有 __ exit __ 方法安排上了.

  • 相关阅读:
    junit单元测试踩过的坑
    Arrays.asList()需要注意的点
    oracle数据库学习笔记
    实训笔记
    spring事务学习笔记
    java锁
    jvm内存模型
    iOS 应用架构 (三)
    iOS 应用架构 (二)
    iOS 应用架构 (一)
  • 原文地址:https://www.cnblogs.com/chenjieyouge/p/13341700.html
Copyright © 2011-2022 走看看