0

0

总结Python编码需要注意的地方

零下一度

零下一度

发布时间:2017-06-27 09:56:02

|

1325人浏览过

|

来源于php中文网

原创


1、map, filter, reduce
1) map(func, input_list)
将函数应用到输入列表上的每个元素, 如:
input_list = [1, 2, 3, 4, 5]


def pow_elem(x):
   """
   将x做乘方运算
   :param x:
   :return:
   """
   return x * x


def multi_x_y(x, y):
   return x * y


print map(pow_elem, input_list)  # output:[1, 4, 9, 16, 25]

print map(multi_x_y, input_list, input_list)  # output:[1, 4, 9, 16, 25]

立即学习Python免费学习笔记(深入)”;

2) filter(func_or_none, sequence)
过滤筛选出sequence中满足函数返回True的值,组成新的sequence返回,如:
def is_odd(x):
   """
   判断x是否为奇数
   :param x:
   :return:
   """
   return True if x % 2 > 0 else False

print filter(is_odd, input_list)  # output: [1, 3, 5]

3) reduce(function, sequence)
reduce()函数接收的参数和 map()类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收两个参数,reduce()对list的每个元素反复调用函数f,并返回最终结果值。例如:reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) 等价于((((1+2)+3)+4)+5)
print reduce(lambda x, y: x * y, input_list)  # output: 120

2、三元运算
下面两种写法等价:
"Yes" if 2==2 else "No"
("No", "Yes")[2==2]
即:
1) condition_is_true if condition else condition_is_false
2) (if_test_is_false, if_test_is_true)[test]
1)和2)都能实现三元运算, 但是2)较为少见,且不太优雅,同时2)并不是一个短路运算,如下:
5 if True else 5/0 # output: 5
(1/0, 5)[True]    # throw exception-> ZeroDivisionError: integer division or modulo by zero

3、装饰器
1) Python中,我们可以在函数内部定义函数并调用,如:
def hi(name="patty"):
   print("now you are inside the hi() function")

def greet():
       return "now you are in the greet() function"

def welcome():
       return "now you are in the welcome() function"

print(greet())
   print(welcome())
   print("now you are back in the hi() function")
输出结果为:
now you are inside the hi() function
now you are in the greet() function
now you are in the welcome() function
now you are back in the hi() function

2) 也可以将内部函数返回,利用外部函数进行调用, 如:
def hi(name="patty"):
   def greet():
       return "now you are in the greet() function"

def welcome():
       return "now you are in the welcome() function"

return greet if name == 'patty' else welcome


print hi()  #
print hi()() # now you are in the greet() function
上述代码中,hi()调用返回的是一个function对象,从if/else语句中可以判断出,返回的是greet()函数,当我们调用hi()()时,实际上是调用了内部函数greet()。

3)将函数作为参数传递给另一个函数, 如:
def hi():
   return "hi patty!"

def doSomethingBeforeHi(func):
   print("I am doing some boring work before executing hi()")
   print(func())

doSomethingBeforeHi(hi)
输出结果:
I am doing some boring work before executing hi()
hi patty!
至此, 我们已经实现了一个简单的装饰器, 在调用hi()函数之前, 先输出一行,实际应用中可能是一些预处理操作。实际上,装饰器的功能就是在你的核心逻辑执行前后,加上一些通用的功能。

4) 简单装饰器的实现
def a_new_decorator(a_func):

def wrapTheFunction():
       print("I am doing some boring work before executing a_func()")

a_func()    # call this function

print("I am doing some boring work after executing a_func()")

return wrapTheFunction

def a_function_requiring_decoration():
   print("I am the function which needs some decoration to remove my foul smell")

a_function_requiring_decoration()
#outputs: "I am the function which needs some decoration to remove my foul smell"

a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)
#now a_function_requiring_decoration is wrapped by wrapTheFunction()

a_function_requiring_decoration()
# I am doing some boring work before executing a_func()
# I am the function which needs some decoration to remove my foul smell
# I am doing some boring work after executing a_func()

5) 注解形式
@a_new_decorator
def b_function_requiring_decoration():
   print("I am the another function which needs some decoration to remove my foul smell")

b_function_requiring_decoration()
# I am doing some boring work before executing a_func()
# I am the another function which needs some decoration to remove my foul smell
# I am doing some boring work after executing a_func()
此处@a_new_decorator就等价于a_new_decorator(b_function_requiring_decoration)

6) 获取name
对于4)中的a_function_requiring_decoration, 我们打印print(a_function_requiring_decoration.__name__) 得到的结果是wrapTheFunction,而实际上我们希望得到的是a_func所对应的a_function_requiring_decoration函数名,Python为我们提供了wraps用来解决这个问题。
from functools import wraps
def a_new_decorator(a_func):
   @wraps(a_func)
   def wrapTheFunction():
       print("I am doing some boring work before executing a_func()")

a_func()

print("I am doing some boring work after executing a_func()")

return wrapTheFunction

7) 装饰器的一些应用场景
用户认证
def requires_auth(f):
   @wraps(f)
   def decorated(*args, **kwargs):
       auth = {"username": "patty", "password": "123456"}
       if not check_auth(auth['username'], auth['password']):
           authenticate()
       return f(*args, **kwargs)

def check_auth(username, password):
       print "Starting check auth..."
       return True if (username == 'patty' and password == '123456') else False


   def authenticate():
       print "Already authenticate"
   return decorated

@requires_auth
def welcome():
   return "Welcome patty!"

print welcome()

日志记录
def logit(func):
   @wraps(func)
   def with_logging(*args, **kwargs):
       print(func.__name__ + " was called")
       return func(*args, **kwargs)
   return with_logging

@logit
def addition_func(x):
   """Do some math."""
   return x + x


result = addition_func(4)
将会打印:addition_func was called

8)带参数的装饰器
from functools import wraps

精美淘宝客单页面 zblog模板
精美淘宝客单页面 zblog模板

采用zblog修改的模板,简单方便,直接解压上传到空间即可使用,页面简单,适合SEO,导航,次导航,最新文章列表,随机文章列表全部都有,网站采用扁平结构,非常适用淘宝客类小站,所有文章都在根目录下。所有需要修改的地方在网页上各个地方都有标注说明,一切在网站后台都可以修改,无须修改任何程序代码,是新手的不二选择。后台登陆地址: 域名/login.asp用户名:admin (建议不要修改)密码:adm

下载

def logit(logfile='out.log'):
   def logging_decorator(func):
       @wraps(func)
       def wrapped_function(*args, **kwargs):
           log_string = func.__name__ + " was called"
           print(log_string)
           # Open the logfile and append
           with open(logfile, 'a') as opened_file:
               # Now we log to the specified logfile
               opened_file.write(log_string + '\n')
       return wrapped_function
   return logging_decorator

@logit()
def myfunc1():
   pass

myfunc1()
# Output: myfunc1 was called
# A file called out.log now exists, with the above string

@logit(logfile='func2.log')
def myfunc2():
   pass

myfunc2()

9) 用类作为装饰器
import os
class Logit(object):
   def __init__(self, log_file):
       self.log_file = log_file

def __call__(self, func):
       with open(self.log_file, 'a') as fout:
           log_msg = func.__name__ + " was called"
           fout.write(log_msg)
           fout.write(os.linesep)
       # Now, send a notification
       self.notify()

def notify(self):
       # logit only logs, no more
       pass

class EmailLogit(Logit):
   '''
   A logit implementation for sending emails to admins
   when the function is called.
   '''
   def __init__(self, log_file, email='admin@myproject.com'):
       self.email = email
       super(EmailLogit, self).__init__(log_file)

def notify(self):
       # Send an email to self.email
       # Will not be implemented here
       with open(self.log_file, 'a') as f:
           f.write("Do Something....")
           f.write(os.linesep)
           f.write("Email has send to " + self.email)
           f.write(os.linesep)


@Logit("log1.txt")
def myfunc3():
   pass

@EmailLogit("log2.txt")
def myfunc4():
   pass
用类作为装饰器,我们的代码看上去更简洁, 而且还可以通过继承的方式,实现功能的个性化和复用。

4、可变类型
Python中的可变类型包括列表和字典,这些对象中的元素是可改变的,如
>>> foo = ['hi']
>>> foo += ['patty']
>>> foo
['hi', 'patty']
>>> foo[0]='hello'
>>> foo
['hello', 'patty']

>>> fdict = {"name":"patty"}
>>> fdict.update({"age":"23"})
>>> fdict
{'age': '23', 'name': 'patty'}
>>> fdict.update({"age":"25"})
>>> fdict
{'age': '25', 'name': 'patty'}

在方法中,若传入的参数采用可变类型并赋默认值,要注意会出现以下情况:
>>> def add_to(num, target=[]):
...     target.append(num)
...     return target
...
>>> add_to(1)
[1]
>>> add_to(2)
[1, 2]
>>> add_to(3)
[1, 2, 3]
这是因为, 默认参数在方法被定义时进行计算,而不是每次调用时再计算一次。因此, 为了避免出现上述情况, 当我们期待每次方法被调用时,以一个新的空列表进行计算的时候,可采取如下写法:
>>> def add_to(num, target=None):
...     if target is None:
...         target = []
...     target.append(num)
...     return target
...
>>> add_to(1)
[1]
>>> add_to(2)
[2]

5、浅拷贝和深拷贝
Python中,对象的赋值,拷贝(深/浅拷贝)之间是有差异的,如果使用的时候不注意,就可能产生意外的结果。
1) Python中默认是浅拷贝方式
>>> foo = ['hi']
>>> bar = foo
>>> id(foo)
4458211232
>>> id(bar)    
4458211232
>>> bar.append("patty")
>>> bar
['hi', 'patty']
>>> foo
['hi', 'patty']
注意:id(foo)==id(bar),说明foo和bar引用的是同一个对象, 当通过bar引用对list进行append操作时, 由于指向的是同一块内存空间,foo的输出与bar是一致的。

2) 深拷贝
>>> foo
['hi', {'age': 20, 'name': 'patty'}]
>>> import copy
>>> slow = copy.deepcopy(foo)
>>> slow
['hi', {'age': 20, 'name': 'patty'}]
>>> slow[0]='hello'
>>> slow
['hello', {'age': 20, 'name': 'patty'}]
>>> foo
['hi', {'age': 20, 'name': 'patty'}]
注意: 由于slow是对foo的深拷贝,实际上是在内存中新开了一片空间,将foo对象所引用的内容复制到新的内存空间中,因此当对slow对像所引用的内容进行update操作后,更改只体现在slow对象的引用上,而foo对象所引用的内容并没有发生改变。

6、集合Collection
1) defaultdict
对于普通的dict,若是获取不存在的key,会引发KeyError错误,如下:
some_dict = {}
some_dict['colours']['favourite'] = "yellow"
# Raises KeyError: 'colours'
但是通过defaultdict,我们可以避免这种情况的发生, 如下:
import collections
import json
tree = lambda: collections.defaultdict(tree)
some_dict = tree()
some_dict['colours']['favourite'] = "yellow"
print json.dumps(some_dict)
# Works fine, output: {"colours": {"favourite": "yellow"}}

2) OrderedDict
OrderedDict能够按照我们定义字典时的key顺序打印输出字典,改变value的值不会改变key的顺序, 但是,对key进行删除,重新插入后,key会重新排序到dict的尾部。
from collections import OrderedDict

colours = OrderedDict([("Red", 198), ("Green", 170), ("Blue", 160)])
for key, value in colours.items():
   print(key, value)

3)Counter
利用Counter,可以统计特定项的出现次数,如:
from collections import Counter

colours = (
   ('Yasoob', 'Yellow'),
   ('Ali', 'Blue'),
   ('Arham', 'Green'),
   ('Ali', 'Black'),
   ('Yasoob', 'Red'),
   ('Ahmed', 'Silver'),
)

favs = Counter(name for name, colour in colours)
print(favs)
# Counter({'Yasoob': 2, 'Ali': 2, 'Arham': 1, 'Ahmed': 1})

4)deque
deque是一个双端队列,可在头尾分别进行插入,删除操作, 如下:
from collections import deque
queue_d = deque()
queue_d.append(1)
queue_d.append(2)
print queue_d  # deque([1, 2])
queue_d.appendleft(3)
print queue_d  # deque([3, 1, 2])

queue_d.pop()
print queue_d  # deque([3, 1])
queue_d.popleft()
print queue_d  # deque([1])

deque可以设置队列的最大长度,当元素数目超过最大长度时,会从当前带插入方向的反方向删除相应数目的元素,如下:
queue_c = deque(maxlen=5, iterable=[2, 4, 6])
queue_c.extend([7, 8])
print queue_c  # deque([2, 4, 6, 7, 8], maxlen=5)
queue_c.extend([10, 12])
print(queue_c)  # deque([6, 7, 8, 10, 12], maxlen=5)
queue_c.extendleft([18])
print(queue_c)  # deque([18, 6, 7, 8, 10], maxlen=5)

5)nametuple
tuple是不可变的列表,不可以对tuple中的元素重新赋值,我们只能通过index去访问tuple中的元素。nametuple可看做不可变的字典,可通过name去访问tuple中的元素。如:
from collections import namedtuple

Animal = namedtuple('Animal', 'name age type')
perry = Animal(name="perry", age=31, type="cat")

print(perry)
# Output: Animal(name='perry', age=31, type='cat')

print(perry.name)
# Output: 'perry'

print(perry[0])
# Output: 'perry'

print(perry._asdict())
# Output: OrderedDict([('name', 'perry'), ('age', 31), ('type', 'cat')])

7、Object introspection
1) dir: 列举该对象的所有方法
2)type: 返回对象的类型
3)id: 返回对象的id

8、生成器
1)list
>>> squared = [x**2 for x in range(10)]
>>> squared
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
2) dict
{v: k for k, v in some_dict.items()}
3) set
>>> squared = {x**2 for x in range(10)}
>>> squared
set([0, 1, 4, 81, 64, 9, 16, 49, 25, 36])

9、异常处理
try:
   print('I am sure no exception is going to occur!')
except Exception:
   print('exception')
else:
   # any code that should only run if no exception occurs in the try,
   # but for which exceptions should NOT be caught
   print('This would only run if no exception occurs. And an error here '
         'would NOT be caught.')
finally:
   print('This would be printed in every case.')

# Output: I am sure no exception is going to occur!
# This would only run if no exception occurs.
# This would be printed in every case.
else中的语句会在finally之前执行。

10、内置方法
a_list = [[1, 2], [3, 4], [5, 6]]
print(list(itertools.chain.from_iterable(a_list)))
# Output: [1, 2, 3, 4, 5, 6]

# or
print(list(itertools.chain(*a_list)))
# Output: [1, 2, 3, 4, 5, 6]


class A(object):
   def __init__(self, a, b, c, d, e, f):
       self.__dict__.update({k: v for k, v in locals().items() if k != 'self'})

11、for-else语句
for语句的正常结束方式有两种:一是在满足特定条件的情况下break跳出循环,二是所有条件循环结束。 for-else中的else语句只有在所有条件都经过判断然后正常结束for循环的情况下,才被执行,如下:
for x in range(1, 10, 2):
   if x % 2 == 0:
       print "found even of %d"%x
       break
else:
   print "not foud even"
# output: not foud even

12、兼容Python 2+和Python 3+
1) 利用 __future__模块在Python 2+的环境中引用Python 3+的模块
2)兼容的模块导入方式
try:
   import urllib.request as urllib_request  # for Python 3
except ImportError:
   import urllib2 as urllib_request  # for Python 2

 

Reference: 

 

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

智谱清言 - 免费全能的AI助手
智谱清言 - 免费全能的AI助手

智谱清言 - 免费全能的AI助手

相关专题

更多
batoto漫画官网入口与网页版访问指南
batoto漫画官网入口与网页版访问指南

本专题系统整理batoto漫画官方网站最新可用入口,涵盖最新官网地址、网页版登录页面及防走失访问方式说明,帮助用户快速找到batoto漫画官方平台,稳定在线阅读各类漫画内容。

56

2026.02.25

Steam官网正版入口与注册登录指南_新手快速进入游戏平台方法
Steam官网正版入口与注册登录指南_新手快速进入游戏平台方法

本专题系统整理Steam官网最新可用入口,涵盖网页版登录地址、新用户注册流程、账号登录方法及官方游戏商店访问说明,帮助新手玩家快速进入Steam平台,完成注册登录并管理个人游戏库。

6

2026.02.25

TypeScript全栈项目架构与接口规范设计
TypeScript全栈项目架构与接口规范设计

本专题面向全栈开发者,系统讲解基于 TypeScript 构建前后端统一技术栈的工程化实践。内容涵盖项目分层设计、接口协议规范、类型共享机制、错误码体系设计、接口自动化生成与文档维护方案。通过完整项目示例,帮助开发者构建结构清晰、类型安全、易维护的现代全栈应用架构。

5

2026.02.25

Python数据处理流水线与ETL工程实战
Python数据处理流水线与ETL工程实战

本专题聚焦 Python 在数据工程场景下的实际应用,系统讲解 ETL 流程设计、数据抽取与清洗、批处理与增量处理方案,以及数据质量校验与异常处理机制。通过构建完整的数据处理流水线案例,帮助开发者掌握数据工程中的性能优化思路与工程化规范,为后续数据分析与机器学习提供稳定可靠的数据基础。

0

2026.02.25

Java领域驱动设计(DDD)与复杂业务建模实战
Java领域驱动设计(DDD)与复杂业务建模实战

本专题围绕 Java 在复杂业务系统中的建模与架构设计展开,深入讲解领域驱动设计(DDD)的核心思想与落地实践。内容涵盖领域划分、聚合根设计、限界上下文、领域事件、贫血模型与充血模型对比,并结合实际业务案例,讲解如何在 Spring 体系中实现可演进的领域模型架构,帮助开发者应对复杂业务带来的系统演化挑战。

0

2026.02.25

Golang 生态工具与框架:扩展开发能力
Golang 生态工具与框架:扩展开发能力

《Golang 生态工具与框架》系统梳理 Go 语言在实际工程中的主流工具链与框架选型思路,涵盖 Web 框架、RPC 通信、依赖管理、测试工具、代码生成与项目结构设计等内容。通过真实项目场景解析不同工具的适用边界与组合方式,帮助开发者构建高效、可维护的 Go 工程体系,并提升团队协作与交付效率。

18

2026.02.24

Golang 性能优化专题:提升应用效率
Golang 性能优化专题:提升应用效率

《Golang 性能优化专题》聚焦 Go 应用在高并发与大规模服务中的性能问题,从 profiling、内存分配、Goroutine 调度、GC 机制到 I/O 与锁竞争逐层分析。结合真实案例讲解定位瓶颈的方法与优化策略,帮助开发者建立系统化性能调优思维,在保证代码可维护性的同时显著提升服务吞吐与稳定性。

9

2026.02.24

Golang 面试题精选:高频问题与解答
Golang 面试题精选:高频问题与解答

Golang 面试题精选》系统整理企业常见 Go 技术面试问题,覆盖语言基础、并发模型、内存与调度机制、网络编程、工程实践与性能优化等核心知识点。每道题不仅给出答案,还拆解背后的设计原理与考察思路,帮助读者建立完整知识结构,在面试与实际开发中都能更从容应对复杂问题。

5

2026.02.24

Golang 运行与部署实战:从本地到云端
Golang 运行与部署实战:从本地到云端

《Golang 运行与部署实战》围绕 Go 应用从开发完成到稳定上线的完整流程展开,系统讲解编译构建、环境配置、日志与配置管理、容器化部署以及常见运维问题处理。结合真实项目场景,拆解自动化构建与持续部署思路,帮助开发者建立可靠的发布流程,提升服务稳定性与可维护性。

5

2026.02.24

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.4万人学习

Django 教程
Django 教程

共28课时 | 4.5万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号