1.python的函数参数传递:
id()查看引用变量的内存地址
对象分为可更改对象和不可更改对象,python中,strings, tuples, numbers属于不可更改的对象,list, dict, set等是可更改对象
当一个引用传递给函数的时候,函数自动复制一份引用,这个函数里的引用和外边的引用没有半毛关系了.所以第一个例子里(a = 1)函数把引用指向了一个不可变对象,当函数返回的时候,外面的引用没半毛感觉.而第二个例子(a = [])就不一样了,函数内的引用指向的是可变对象,对它的操作就和定位了指针地址一样,在内存里进行修改.
2.python元类:
python元类:type是python内置的元类,元类就是类的类(很多情况下都不用到元类)
假设创建一个对象a = 8,使用a._class_可得到int,a._class_._class_即可得到type(type即元类)
3.python的三个方法
python中有三个方法,实例方法,类方法,静态方法。实例方法和类方法需要设置默认参数,静态方法不需要。
根据人们的惯用用法,self一般是在实例方法中使用,而cls则一般在类方法中使用,在静态方法中则不需要使用一个默认参数,其实这个默认参数可以换成任何一个名字代替,不会产生任何影响,但python默认实例方法使用self当做默认参数,类方法使用cls作为默认参数。
def foo(x): print "executing foo(%s)"%(x) class A(object): def foo(self,x): print "executing foo(%s,%s)"%(self,x) @classmethod def class_foo(cls,x): print "executing class_foo(%s,%s)"%(cls,x) @staticmethod def static_foo(x): print "executing static_foo(%s)"%x a=A()
\ | 实例方法 | 类方法 | 静态方法 |
---|---|---|---|
a = A() | a.foo(x) | a.class_foo(x) | a.static_foo(x) |
A | 不可用 | A.class_foo(x) | A.static_foo(x) |
4.python的类变量和实例变量:
class Test(object): num_of_instance = 0 def __init__(self, name): self.name = name Test.num_of_instance += 1
类变量:
是可在类的所有实例之间共享的值(也就是说,它们不是单独分配给每个实例的)。例如下例中,num_of_instance 就是类变量,用于跟踪存在着多少个Test 的实例。
实例变量:
实例化之后,每个实例单独拥有的变量。
5.python自省
这个也是python彪悍的特性.
自省就是面向对象的语言所写的程序在运行时,所能知道对象的类型.简单一句就是运行时能够获得对象的类型.比如type(),dir(),getattr(),hasattr(),isinstance().
6.python字典推导式和列表推导式
列表推导式:ls = [i for i in range(10)]
字典推导式:d = {key: value for (key, value) in iterable}
7.python中单下划线和双下划线
class MyClass(): ... def __init__(self): ... self.__superprivate = "Hello" ... self._semiprivate = ", world!" ... >>> mc = MyClass() >>> print mc.__superprivate Traceback (most recent call last): File "", line 1, in AttributeError: myClass instance has no attribute '__superprivate' >>> print mc._semiprivate , world! >>> print mc.__dict__ {'_MyClass__superprivate': 'Hello', '_semiprivate': ', world!'}
__foo__
:一种约定,Python内部的名字,用来区别其他用户自定义的命名,以防冲突,就是例如__init__()
,__del__()
,__call__()
这些特殊方法
_foo
:一种约定,用来指定变量私有.程序员用来指定私有变量的一种方式.不能用from module import * 导入,其他方面和公有一样访问;
__foo
:这个有真正的意义:解析器用_classname__foo
来代替这个名字,以区别和其他类相同的命名,它无法直接像公有成员一样随便访问,通过对象名._类名__xxx这样的方式可以访问.
8.字符串格式化%和.format
当然是.format好用,%不能同时传递一个变量和元组
9.迭代器和生成器
生成器是只能使用一次的迭代器
yield相当于一个return的东西,返回一个生成器
10.*args 和**kwargs
*args:当args与默认参数和位置参数混用的情况下,注意顺序
有两种符合的顺序,一种是(位置参数,默认参数,*args),一种是(位置参数,*args, 默认参数),无论哪种都是位置参数位于最前面。
'''
def foo(x, *args):
print(x)
print(*args)
foo(1,2,3,4,5)
'''
'''
def foo(x, y = 1, *args):
print(x)
print(y) #y = 1被覆盖了,输出y = 2
print(*args)
foo(1,2,3,4,5)
'''
'''
def foo(x, *args, y = 1):
print(x)
print(*args)
print(y) #这里由于之前的*args已经接受了所有剩余的参数,所以默认值不会变
foo(1,2,3,4,5)
'''
'''
def foo(*args): #从形参角度来看
print(args)
foo(1,2,3,4,5) #返回一个元组
'''
'''
def foo(x,y,z): #从实参的角度来看
print(x, y, z)
foo(*(1, 2, 3))
'''
*args:将参数打包成元组给函数体调用。
**kwargs:将参数和值打包成字典给函数体调用。
def foo(*args):
print(args, type(args))
foo(1,2,3,4,5)
def func(**kwargs):
print(kwargs, type(kwargs))
func(a = 2, b = 1, c = 3)
output:
(1, 2, 3, 4, 5)
{'a': 2, 'b': 1, 'c': 3}