改善python程序的91建议记录

使用else子句简化循环(异常处理)

  • 案例1 执行sql异常时处理
python 复制代码
def save(db, obj):
    try:
        # save attr1
        db.execute('a sql stmt', obj.attr1)
        # save attr2
        db.execute('another sql stmt', obj.attr2)
    except DBError:
        db.rollback()
    else:
        db.commit()
  • 案例2
python 复制代码
def print_prime2(n):
    for i in range(2, n):
        for j in range(2, i):
            if i % j == 0:
                break
        else:
            print('%d is a prime number'+  str(i))
print_prime2(111)

使用join连接字符串

  • S1+S2+S3+.......+SN,执行一次+操作便会在内存中申请一块新的内存空间,并将上一次操作的结果和本次操作的右操作数复制到新申请的内存空间,即当执行S1+S2的时候会申请一块内存,并将S1、S2复制到该内存中,依次类推,字符串的连接,特别是大规模字符串的处理,应该尽量优先使用join而不是+。
  • 案例验证
ini 复制代码
a,b,c = 1,'aa','Filte'
a_string = ','.join([str(a),b,c,"测试"])
print(a_string)

return: 1,aa,Filte,测试

[]、()和{}:一致的容器初始化形式

  • 列表解析语法中的表达式可以是简单表达式,也可以是复杂表达式,甚至是函数。
ini 复制代码
def f(v):
    if v%2 == 0:
        v = v**2
    else:
        v = v+1
    return v

[f(v) for v in [2,3,4,-1] if v>0]
return: [4, 4, 16]
  • 迭代文件对象
ini 复制代码
fh = open("test.txt", "r")
result = [i for i in fh if "abc" in i]  #
文件句柄可以当做可迭代对象
print result

深、浅拷贝差异

  • 详细demo
  • 由于通过copy.copy()得到的customer2是customer1的一个浅拷贝,它仅仅拷贝了pizzalist里面对象的地址而不对对应地址所指向的具体内容(即具体的pizza)进行拷贝,因此customer2中的pizzaList所指向的具体内容是和customer1中一样的.
  • 实际上在包含引用的数据结构中,浅拷贝并不能进行彻底的拷贝,当存在列表、字典等不可变对象的时候,它仅仅拷贝其引用地址。要解决上述问题需要用到深拷贝,深拷贝不仅拷贝引用也拷贝引用所指向的对象,因此深拷贝得到的对象和原对象是相互独立的
python 复制代码
class Pizza(object):
    def __init__(self,name,size,price):
        self.name = name
        self.size = size
        self.price = price

    def getPizzaInfo(self):
        return self.name,self.size,self.price

    def showPizzaInfo(self):
        print("Pizza name:"+self.name)
        print("Pizza size:"+str(self.size))
        print("Pizza price:"+str(self.price))

    def changeSize(self,size):
        self.size = size

    def changePrice(self,price):
        self.price = price

class Order(object):
    def __init__(self,name):
        self.costomername = name
        self.pizzaList = []
        self.pizzaList.append(Pizza("Mushroom",12,30))

    def ordermore(self,pizza):
        self.pizzaList.append(pizza)

    def changeName(self,name):
        self.costomername=name

    def getorderdetail(self):
        print("customer name:"+self.costomername)
        for i in self.pizzaList:
            i.showPizzaInfo()
            print(id(i))

    def getPizza(self,number):
        return self.pizzaList[number]

customer1=Order("zhangSan")
customer1.ordermore(Pizza("seafood",9,40))
customer1.ordermore(Pizza("fruit",12,35))
print("customer1 order infomation:")
customer1.getorderdetail()
print("-------------------------------")

# customer2=copy.copy(customer1)  #浅拷贝
customer2=copy.deepcopy(customer1) # 深拷贝
print("order 2 customer name:"+customer2.costomername)
customer2.changeName("li")
customer2.getPizza(2).changeSize(9)
customer2.getPizza(2).changePrice(30)
print("customer2 order infomation:")
customer2.getorderdetail()
print("-------------------------------------")

customer1.getorderdetail()

深入掌握ConfigParser

  • 首先就是getboolean()这个函数。getboolean()根据一定的规则将配置项的值转换为布尔值,调用getboolean('section1', 'optioin1')时,将返回False。不过getboolean()的真值规则值得一说:除了0之外,no、false和off都会被转义为False,而对应的1、yes、true和on则都被转义为True,其他值都会导致抛出ValueError异常。
  • ConfigParser支持的配置文件格式里,有一个[DEFAULT]节,当读取的配置项在不在指定的节里时,ConfigParser将会到[DEFAULT]节中查找
csharp 复制代码
cfg.ini配置文件:
[DEFAULT]
in_default = 'an option value in default'
[section2]

[section1]
option1=True

conf = configparser.ConfigParser()
conf.read('cfg.ini')
print(conf.getboolean('section1', 'option1'))
print(conf.get('section2', 'in_default'))

##输出
True
'an option value in default'
##
  • 在Python中字符串格式化可以使用以下语法,常见的SQLAlchemy应用程序的配置文件,通过这个配置文件能够获取不同的数据库配置相应的连接字符串,即conn_str。如你所见,conn_str定义在[DEFAULT]中,但当它通过不同的节名来获取格式化后的值时,根据不同配置,得到不同的值
ini 复制代码
###cfg.ini
[DEFAULT]
conn_str = %(dbn)s://%(user)s:%(pw)s@%(host)s:%(port)s/%(db)s
dbn = mysql
user = root
host=192.168.127.2
port = 3306

[db1]
user = test1
pw=test_123
db=ucds_1

[db2]
user = test2
host=192.168.127.1
pw=test_123
db=ucds_2
port=3308

conf = configparser.ConfigParser()
conf.read('cfg.ini')
print("mysql conn",conf.get('db1', 'conn_str'))
print("mysql conn",conf.get('db2', 'conn_str'))

##输出
mysql conn mysql://test1:test_123@192.168.127.2:3306/ucds_1
mysql conn mysql://test2:test_123@192.168.127.1:3308/ucds_2
##

用mixin模式让程序更加灵活

ruby 复制代码
class TelMixin:
    def telfunc(self, num):
        self.name = num
        print("call Phone ",self.name)

class SmsMixin:
    def smsfunc(self, num):
        self.name = num
        print("send Sms info:",self.name)

class SongMixin:
    def songfunc(self):
        print("我可以放音乐")

class Phone(TelMixin,SmsMixin,SongMixin):
    def __init__(self):
        pass

class Ipod(SongMixin):
    def __init__(self, sn):
        self.num = num


p = Phone()
p.telfunc("110")
p.smsfunc("110")
p.songfunc()

静态代码分析工具

  • 它可以帮助开发者检查代码中的错误、编码规范问题以及代码风格问题
sql 复制代码
[devops@my-dev ccod_check_back_info]$ pip install pylint

[devops@my-dev ccod_check_back_info]$ pylint atest.py 
************* Module atest
atest.py:5:17: C0303: Trailing whitespace (trailing-whitespace)
atest.py:7:0: C0301: Line too long (119/100) (line-too-long)
atest.py:9:0: C0301: Line too long (170/100) (line-too-long)
atest.py:1:0: C0114: Missing module docstring (missing-module-docstring)
atest.py:4:0: C0116: Missing function or method docstring (missing-function-docstring)
atest.py:17:0: C0116: Missing function or method docstring (missing-function-docstring)
atest.py:19:4: C0103: Variable name "Passwd" doesn't conform to snake_case naming style (invalid-name)
atest.py:22:12: C0103: Variable name "Passwd" doesn't conform to snake_case naming style (invalid-name)

-----------------------------------
  • ssh-keygen -m PEM -t rsa 需要特殊格式,
相关推荐
uzong2 小时前
技术故障复盘模版
后端
GetcharZp2 小时前
基于 Dify + 通义千问的多模态大模型 搭建发票识别 Agent
后端·llm·agent
桦说编程2 小时前
Java 中如何创建不可变类型
java·后端·函数式编程
IT毕设实战小研2 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
wyiyiyi3 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
阿华的代码王国4 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
Jimmy4 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
AntBlack4 小时前
不当韭菜V1.1 :增强能力 ,辅助构建自己的交易规则
后端·python·pyqt
bobz9655 小时前
pip install 已经不再安全
后端
寻月隐君5 小时前
硬核实战:从零到一,用 Rust 和 Axum 构建高性能聊天服务后端
后端·rust·github