python语法笔记(三)

1. 动态类型

python的变量不需要声明,在赋值时,变量可以赋值为任意的值。这和Python的动态类型语言相关。

python对象是存在于内存中的实体,代码中写对象名,只是指向该对象的引用。引用和对象分离,是python动态类型的核心。引用可以随时指向一个新的对象:

a = 3
a = 'at'
#开始a指向对象3,a为对象3的一个引用
#执行 a = 'at',a指向了另一个对象,而原来的对象 3,如果没有任何一个变量指向它,则会被自动回收
a = 10
b = a
a = a + 2
#此时b指向对象10, 而a指向对象12.

a = [1,2,3,4]
b = a
a[1] = 100
print b 
# 1 100 3 4
#列表、字典为 mutable对象,通过某个引用使这些对象内部的数据发生改变,
#所有指向该对象的引用都会继续指向发生改变后的对象

#整数、字符串、元组等类型为immutable对象,无法通过某个引用是的对象内部数据发生改变。只能
#是该引用指向了一个新的对象

列表可以通过引用其元素,改变对象自身(in-place change)。这种对象类型,称为可变数据对象(mutable object),词典也是。

而像之前的数字和字符串,不能改变对象本身,只能改变引用的指向,称为不可变数据对象(immutable object)。

2. 从动态类型看函数的参数传递

函数的参数传递,本质上传递的是引用。

def f(x):
    x = 100
    print x

a = 1
f(a)
print a

#函数f,参数a 为对象1的引用,在f内部通过x=100赋值,试图修改函数f外的对象1.但是由于1是整数
#为immutable的对象,因此在函数f内部的x指向了一个新的对象,而原来的f外部的对象1并未发生改变。


def f(x):
    x[1] = 100
    print x

a = [1,2,3,4]
f(a)
pirnt a
#函数f,参数a 为对象list [1,2,3,4] 的引用,在f内部通过x[1]=100赋值,试图修改函数f外的对象
#列表 a。a为mutable对象,可以被改变,因此函数f外部的列表a最终发生改变。变为 [1, 100, 3, 4]

 2. 特殊方法

python是一种多范式的语言,可以使用面向对象、面向过程、函数式、声明式的方法来编写python。python的多范式依赖于python中的特殊方法。

python特殊方法也叫作魔法方法,特殊方法名前后各有两个下划线。当对象中定义了特殊方法的时候,python会在执行的时候对他们进行“特殊优待”。比如定义了__init__()的类,会在创建对象的时候自动执行__init__()方法。

(2.1)运算符

python运算符是通过调用对象内部的特殊方法来实现的,比如 'abc' + 'xyz' 是通过调用 'abc'.__add__('xyz')来实现。在Python中,两个对象是否能进行加法运算,首先就要看相应的对象是否有__add__()方法。一旦相应的对象有__add__()方法,即使这个对象从数学上不可加,我们都可以用加法的形式,来表达obj.__add__()所定义的操作。在Python中,运算符起到简化书写的功能,但它依靠特殊方法实现。

(2.2)内置函数

类似运算符,许多内置函数也是调用对象的特殊方法。

len([1,2,3])      # 返回表中元素的总数
实际执行
[1,2,3].__len__()

 (2.3)表元素引用

表元素的引用方式:
li = [1, 2, 3, 4, 5, 6]
print(li[3])

Python发现并理解[]符号,然后调用__getitem__()方法
li = [1, 2, 3, 4, 5, 6]
print(li.__getitem__(3))

 (2.4)函数

在python中,函数也是一个对象。任何一个有特殊方法__call__()的对象都可视为一个函数。

class SampleMore(object):
    def __call__(self, a):
        return a + 5

add = SampleMore()     # A function object
print(add(2))          # Call function    
map(add, [2, 4, 5])    # Pass around function object

3.上下文管理器

上下文管理器(context manager)是Python2.5开始支持的一种语法,用于规定某个对象的使用范围。一旦进入或者离开该使用范围,会有特殊操作被调用 (比如为对象分配或者释放内存)。它的语法形式是with...as...

例如文件的读写:

# without context manager
f = open("new.txt", "w")
print(f.closed)               # whether the file is open
f.write("Hello World!")
f.close()
print(f.closed)



# with context manager
with open("new.txt", "w") as f:
    print(f.closed)
    f.write("Hello World!")
print(f.closed)

上下文管理器有隶属于它的程序块。当隶属的程序块执行结束的时候(也就是不再缩进),上下文管理器自动关闭了文件 (我们通过f.closed来查询文件是否关闭)。
我们相当于使用缩进规定了文件对象f的使用范围。

 当我们使用上下文管理器的语法时,我们实际上要求Python在进入程序块之前调用对象的__enter__()方法,在结束程序块的时候调用__exit__()方法。

自定义上下文管理器

任何定义了__enter__()和__exit__()方法的对象都可以用于上下文管理器。文件对象f是内置对象,所以f自动带有这两个特殊方法,不需要自定义。

# customized object

class VOW(object):
    def __init__(self, text):
        self.text = text
    def __enter__(self):
        self.text = "I say: " + self.text    # add prefix
        return self                          # note: return an object
    def __exit__(self,exc_type,exc_value,traceback):
        self.text = self.text + "!"          # add suffix


with VOW("I'm fine") as myvow:
    print(myvow.text)

print(myvow.text)

 注意: __exit__()中有四个参数。当程序块中出现异常(exception),__exit__()的参数中exc_type, exc_value, traceback用于描述异常。我们可以根据这三个参数进行相应的处理。如果正常运行结束,这三个参数都是None。

参考:

http://www.cnblogs.com/vamei/archive/2012/09/13/2682778.html

原文地址:https://www.cnblogs.com/gtarcoder/p/5027867.html