Python全栈-基础问题锦集

For else

在 python 中,for … else 表示这样的意思,for 中的语句和普通的没有区别,else 中的语句会在循环正常执行完(即 for 不是通过 break 跳出而中断的)的情况下执行,while … else 也是一样。

原文:for loops also have an else clause which most of us are unfamiliar with. The else clause executes after the loop completes normally. This means that the loop did not encounter a break statement. They are really useful once you understand where to use them. I, myself, came to know about them a lot later.

for  i in range(3):
    if i == 2:
        print(i)
        break

else:
    print(0)

for i in range(3):
    if i == 2:
        print(i)
else:
    print(0)


for n in range(2, 10):
    for x in range(2, n):
        if n % x == 0:
            print(n, 'equals', x, '*', n/x)
            break

for n in range(2, 10):
    for x in range(2, n):
        if n % x == 0:
            print( n, 'equals', x, '*', n/x)
            break
    else:
        # loop fell through without finding a factor
        print(n, 'is a prime number')      
2
2
0
4 equals 2 * 2.0
6 equals 2 * 3.0
8 equals 2 * 4.0
9 equals 3 * 3.0
2 is a prime number
3 is a prime number
4 equals 2 * 2.0
5 is a prime number
6 equals 2 * 3.0
7 is a prime number
8 equals 2 * 4.0
9 equals 3 * 3.0

Try except else

```
try:
<语句>        #运行别的代码
except <名字>:
<语句>        #如果在try部份引发了'name'异常
except <名字>,<数据>:
<语句>        #如果引发了'name'异常,获得附加的数据
else:
<语句>        #如果没有异常发生
```
* try的工作原理是,当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。
    + 如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发新的异常)。
    + 如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印默认的出错信息)。
    + 如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。
try的工作原理是,当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。
    + 如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发新的异常)。
    如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印默认的出错信息)。
    + 如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。
def A():
    try:
        print(1)
        a=3//0
    except:
        print(2)
        return
    finally:
        print(3)
    print(4)
    return

def B():   
    try:
        fh = open("testfile", "w")
        fh.write("这是一个测试文件,用于测试异常!!")
    except IOError:
        print ("Error: 没有找到文件或读取文件失败")
    else:
        print ("内容写入文件成功")
        fh.close()
    finally:
        print("Always to be excuted!")

A()
B()

try:
    age=int(input('Enter your age: '))
except:
    print ('You have entered an invalid value.')
else:
    if age <= 21:
        print('You are not allowed to enter, you are too young.')
    else:
        print('Welcome, you are old enough.')
1
2
3
内容写入文件成功
Always to be excuted!
Enter your age: 25
Welcome, you are old enough.

Try finally return

原文:
A finally clause is always executed before leaving the try statement, whether an exception has occurred or not. When an exception has occurred in the try clause and has not been handled by an except clause (or it has occurred in a except or else clause), it is re-raised after the finally clause has been executed. The finally clause is also executed “on the way out” when any other clause of the try statement is left via a break, continue or return statement. A more complicated example (having except and finally clauses in the same try statement works as of Python 2.5):
So once the try/except block is left using return, which would set the return value to given - finally blocks will always execute, and should be used to free resources etc. while using there another return - overwrites the original one.
def func1():
    try:
        return 1
    finally:
        return 2

def func2():
    try:
        raise ValueError()
    except:
        return 1
    finally:
        return 3

print(func1())
print(func2())
2
3
  • 上面 except、except X、else是可选项,但是:

    在上面展示的完整语句中try/ except/ else/ finally所出现的顺序是try–>except X–>except–>else–>finally。else和finally如果存在的话,else必须在finally之前,finally必须在整个程序的最后。

    else的存在必须以except或except X存在为前提,如果没有except而在tryblock中使用esle的话,会出现语法错误。

装饰器

A decorator is the name used for a software design pattern. Decorators dynamically alter the functionality of a function, method, or class without having to directly use subclasses or change the source code of the function being decorated. 
参考:https://wiki.python.org/moin/PythonDecorators
    https://realpython.com/primer-on-python-decorators/
    https://www.cnblogs.com/serpent/p/9445592.html
    https://www.runoob.com/w3cnote/python-func-decorators.html

内置装饰器

参考: https://docs.python.org/3/library/functions.html
      https://blog.csdn.net/felix_yujing/article/details/79749944
@classmethod 类方法的第一个参数是一个类,是将类本身作为操作的方法。类方法被哪个类调用,就传入哪个类作为第一个参数进行操作。
@property 使调用类中的方法像引用类中的字段属性一样。被修饰的特性方法,内部可以实现处理逻辑,但对外提供统一的调用方式。
@staticmethod 将类中的方法装饰为静态方法,即类不需要创建实例的情况下,可以通过类名直接引用。到达将函数功能与实例解绑的效果。
# @property 使调用类中的方法像引用类中的字段属性一样。被修饰的特性方法,内部可以实现处理逻辑,但对外提供统一的调用方式。
# coding: utf-8
class TestClass:
    name = "test"

    def __init__(self, name):
        self.name = name

    @property
    def sayHello(self):
        print ("hello", self.name)

cls = TestClass("felix")
print ("通过实例引用属性")
print (cls.name)
print ("像引用属性一样调用@property修饰的方法")
cls.sayHello
通过实例引用属性
felix
像引用属性一样调用@property修饰的方法
hello felix
# @staticmethod 将类中的方法装饰为静态方法,即类不需要创建实例的情况下,可以通过类名直接引用。到达将函数功能与实例解绑的效果。
# coding: utf-8
class TestClass:
    name = "test"

    def __init__(self, name):
        self.name = name

    @staticmethod
    def fun(self, x, y):
        return  x + y

cls = TestClass("felix")
print ("通过实例引用方法")
print (cls.fun(None, 2, 3))  # 参数个数必须与定义中的个数保持一致,否则报错

print ("类名直接引用静态方法")
print (TestClass.fun(None, 2, 3)) # 参数个数必须与定义中的个数保持一致,否则报错
print(TestClass.fun(5,6,9))
通过实例引用方法
5
类名直接引用静态方法
5
15
# @classmethod 类方法的第一个参数是一个类,是将类本身作为操作的方法。类方法被哪个类调用,就传入哪个类作为第一个参数进行操作。
# coding: utf-8
class Car(object):
    car = "audi"

    @classmethod
    def value(self, category): # 可定义多个参数,但第一个参数为类本身
        print ("%s car of %s" % (category, self.car))

class BMW(Car):
    car = "BMW"

class Benz(Car):
    car = "Benz"

print ("通过实例调用")
baoma = BMW()
baoma.value("Normal") # 由于第一个参数为类本身,调用时传入的参数对应的时category

print ("通过类名直接调用")
Benz.value("SUV")

Car.value("audi")
通过实例调用
Normal car of BMW
通过类名直接调用
SUV car of Benz
audi car of audi

装饰器基本用法

装饰器参数传递
@装饰器后有参数时
两个装饰器同时修饰一个函数(重点看执行顺序)
装饰器类
#  简单装饰器
def log_time(func):  # 此函数的作用时接受被修饰的函数的引用test,然后被内部函数使用
    def make_decorater():
        print('现在开始装饰')
        func()
        print('现在结束装饰')
    return make_decorater  # log_time()被调用后,运行此函数返回make_decorater()函数的引用make_decorater
 
@log_time  # 此行代码等同于,test=log_time(test)=make_decorater
def test():
    print('我是被装饰的函数')
test()  # test()=make_decorater()
现在开始装饰
我是被装饰的函数
现在结束装饰
# 被装饰的函数有形参时
def log_time(func):
    def make_decorater(*argvs,**kargvs):  # 接受调用语句的实参,在下面传递给被装饰函数(原函数)
        print('Now decorater')
        tmp = func(argvs[0]) # 如果在这里return,则下面的代码无法执行,所以引用并在下面返回
        print('Fininshed decorater') 
        return tmp
    return make_decorater # 因为被装饰函数里有return,所以需要给调用语句(test(2))一个返回

@log_time
def test(num):
    print('I am here .')
    return num + 1

test(9)
Now decorater
I am here .
Fininshed decorater





10
# @装饰器后有参数时
def get_parameter(*args,**kwargs):  # 工厂函数,用来接受@get_parameter('index.html/')的'index.html/'
    def log_time(func):
        def make_decorater():
            print(args,kwargs)
            print('现在开始装饰')
            func()
            print('现在结束装饰')
        return make_decorater
    return log_time
 
@get_parameter('index.html/')
def test():
    print('我是被装饰的函数')
    # return num+1
 
test()  # test()=make_decorater()
('index.html/',) {}
现在开始装饰
我是被装饰的函数
现在结束装饰
#  两个装饰器同时修饰一个函数(重点看执行顺序)
def log_time1(func):
    def make_decorater(*args,**kwargs): 
        print('1现在开始装饰')
        test_func = func(args[0],**kwargs) 
        print('1现在结束装饰') 
        return test_func 
    return make_decorater
 
def log_time2(func):
    def make_decorater(*args,**kwargs):  # 接受调用语句的实参,在下面传递给被装饰函数(原函数)
        print('2现在开始装饰')
        test_func = func(*args,**kwargs)  # 如果在这里return,则下面的代码无法执行,所以引用并在下面返回
        print('2现在结束装饰')
        return test_func  # 因为被装饰函数里有return,所以需要给调用语句(test(2))一个返回,又因为test_func = func(*args,**kwargs)已经调用了被装饰函数,这里就不用带()调用了,区别在于运行顺序的不同。
    return make_decorater
 
@log_time1
@log_time2
def test(num):
    print('我是被装饰的函数')
    return num+1
 
a = test(2)  # test(2)=make_decorater(2)
print(a)
1现在开始装饰
2现在开始装饰
我是被装饰的函数
2现在结束装饰
1现在结束装饰
3
# 重写了我们函数的名字和注释文档(docstring)。幸运的是Python提供给我们一个简单的函数来解决这个问题,那就是functools.wraps。我
# @wraps接受一个函数来进行装饰,并加入了复制函数名称、注释文档、参数列表等等的功能。这可以让我们在装饰器里面访问在装饰之前的函数的属性。

from functools import wraps
def decorator_name(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        if not can_run:
            return "Function will not run"
        return f(*args, **kwargs)
    return decorated
 
@decorator_name
def func():
    return("Function is running")
 
can_run = True
print(func())
print(func.__name__)
# Output: Function is running
 
can_run = False
print(func())
# Output: Function will not run

带参数的装饰器——在函数中嵌入装饰器

来想想这个问题,难道@wraps不也是个装饰器吗?但是,它接收一个参数,就像任何普通的函数能做的那样。那么,为什么我们不也那样做呢? 这是因为,当你使用@my_decorator语法时,你是在应用一个以单个函数作为参数的一个包裹函数。Python里每个东西都是一个对象,而且包括函数!我们可以编写一下能返回一个包裹函数的函数。在函数中嵌入装饰器

我们回到日志的例子,并创建一个包裹函数,能让我们指定一个用于输出的日志文件。
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)
            # 打开logfile,并写入内容
            with open(logfile, 'a') as opened_file:
                
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值