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

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

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 + ”)
       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: 

 

以上就是总结Python编码需要注意的地方的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2269200.html

(0)
上一篇 2025年2月27日 11:06:23
下一篇 2025年2月18日 03:57:49

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • Python是怎么操作文件和目录的?

    Python操作文件和目录 读写文件比较简单,有一点特别注意就好了 windows下Python默认打开的文件以gbk解码,而一般我们的文件是utf-8编码的,所以如果文本含有中文,就会出现异常或者乱码。此时手动添加encoding=&#8…

    编程技术 2025年2月27日
    200
  • python-函数式编程实例教程

      函数式编程是使用一系列函数去解决问题,按照一般编程思维,面对问题时我们的思考方式是“怎么干”,而函数函数式编程的思考方式是我要“干什么”。 至于函数式编程的特点暂不总结,我们直接拿例子来体会什么是函数式编程。  lambda表达式(匿名…

    编程技术 2025年2月27日
    200
  • 一种解释型语言–python的介绍

    python是一种解释型语言 python 2 或 3的选择:   python 2.7是2的最新版本 也是最后一个版本,更新支持至2020年 将会停止更新,但是现在正在使用或已经开发完成的公司在继续使用python2 ,所以更新的这个过渡…

    编程技术 2025年2月27日
    200
  • 总结一些Python的编程技巧

    这篇文章主要介绍了给python初学者的一些编程技巧,皆是基于基础的一些编程习惯建议,需要的朋友可以参考下 交换变量 x = 6y = 5 x, y = y, x print x>>> 5print y>>&g…

    编程技术 2025年2月27日
    200
  • Python常用方法和技巧汇总

    这篇文章主要介绍了收藏的一些python常用方法和技巧,本文讲解了逆转字符串的三种方法、遍历字典的四种方法、遍历list的三种方法、字典排序的方法等python常用技巧和方法,需要的朋友可以参考下 1. 逆转字符串的三种方法1.1. 模拟C…

    编程技术 2025年2月27日
    200
  • Python编程JSON格式的转换、else语句的活用和setdefault方法详解

    这篇文章主要介绍了总结python编程中三条常用的技巧,包括json格式的转换、else语句的活用和setdefault方法的使用,需要的朋友可以参考下 在 python 代码中可以看到一些常见的 trick,在这里做一个简单的小结。jso…

    编程技术 2025年2月27日
    200
  • 适合利用Python合并多个装饰器?

    这篇文章主要介绍了python合并多个装饰器小技巧,本文用改写调用函数的方式实现把多个装饰器合并成一行、一个函数来调用,需要的朋友可以参考下 django程序,需要写很多api,每个函数都需要几个装饰器,例如 @csrf_exempt  @…

    编程技术 2025年2月27日
    200
  • Python如何查找子字符串

    这篇文章主要介绍了python字符串中查找子串小技巧,,需要的朋友可以参考下 如果让你写一个程序检查字符串s2中是不是包含有s1。也许你会很直观的写下下面的代码: #determine whether s1 is a substringof…

    编程技术 2025年2月27日
    200
  • Python中的高级编程一些小技巧总结

    这篇文章主要介绍了介绍python中的一些高级编程技巧,包括推导师和装饰器等重要的进阶知识点,皆为深入学习python开发的必备基本功,需要的朋友可以参考下  正文: 本文展示一些高级的Python设计结构和它们的使用方法。在日常工作中,你…

    编程技术 2025年2月27日
    200
  • 如何对Python进行性能优化

    python的批评者声称python性能低效、执行缓慢,但实际上并非如此:尝试以下6个小技巧,可以加快pytho应用程序。 Python是一门非常酷的语言,因为很少的Python代码可以在短时间内做很多事情,并且,Python很容易就能支持…

    编程技术 2025年2月27日
    200

发表回复

登录后才能评论