美文网首页
python基础题(1)

python基础题(1)

作者: 楠木cral | 来源:发表于2019-01-11 19:40 被阅读0次

1、python传参问题

def fun(a):
    a = 2
fun(a)
print(a)  # 1
a = []
def fun(a):
    a.append(1)
fun(a)
print(a)   # [1]

关键:只需要记住类型是属于对象的,而不是变量。而对象有两种,“可更改”(mutable)与“不可更改”(immutable)对象。在python中,strings, tuples, 和numbers是不可更改的对象,而 list, dict, set 等则是可以修改的对象。(那么在传参之后,如果赋值对象的数据类型数可变的,参数值就会改变,而地址不会变;如果赋值对象数据类型数不可变的,原来的引用地址和值就不会变,但是赋值对象的地址和值是会变的)
例如: 下面a是列表,可变类型,在进行了a.append()操作后,a的值改变,地址不变

a = []
def fun(a):
    print( "func_in",id(a)   # func_in   53629256
    a.append(1)
print ("func_out",id(a))     # func_out   53629256
fun(a)
print(a)   # [1]

再例如:下面a是numbers不可变类型,在进行a=2赋值操作,当时a指向了2这个地址,a地址就变成了2的地址,但是函数出来之后,a的地址还是回到了1地址并没有改变

a = 1
def fun(a):
    print("func_in",id(a))   # func_in 41322472
    a = 2
    print ("re-point",id(a), id(2))   # re-point 41322448 41322448
print("func_out",id(a), id(1))  c# func_out 41322472 41322472
fun(a)
print a  # 1

2、实例方法,类方法@classmethod和静态方法@staticmethod
先看一下:

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()

先说说self和cls,self和cls是对类或者实例的绑定,可以替换别的参数,但是python的约定是这俩,还是不要改的好.
(1)一般方法,我们可以这么调用foo(x),这个函数就是最常用的,它的工作跟任何东西(类,实例)无关。
(2)实例方法,我们知道在类里每次定义方法的时候都需要绑定这个实例,就是foo(self, x),调用时:a.foo(x) (本质其实是foo(a, x))
(3)类方法一样,只不过它传递的是类而不是实例,A.class_foo(x)。
(4)静态方法,其实和普通的方法一样,不需要对谁进行绑定,唯一的区别是调用的时候需要使用a.static_foo(x)或者A.static_foo(x)来调用.


image.png

3、类变量和实例变量
类变量:
​ 是可在类的所有实例之间共享的值(也就是说,它们不是单独分配给每个实例的)。例如下例中,num_of_instance 就是类变量,用于跟踪存在着多少个Test 的实例。
实例变量:
实例化之后,每个实例单独拥有的变量。

class Test(object):
    num_of_instance = 0

    def __init__(self, name):
        self.name = name
        Test.num_of_instance += 1
if __name__ == '__main__':
    print(Test.num_of_instance)  # 0
    t1 = Test('jack')
    print(Test.num_of_instance)  # 1
    t2 = Test('lucy')
    print(t1.name, t1.num_of_instance)   # jack 2
    print(t2.name, t2.num_of_instance)  # lucy 2

再看个例子:

class Person:
    name="aaa"
p1=Person()
p2=Person()
p1.name="bbb"
print(p1.name)  # bbb
print( p2.name)  # aaa
print( Person.name)  # aaa

这里name就是类变量,参考上面讲的传参问题,因为“aaa”是字符串类型,所以实例p1调用这个类变量,并不会改变类变量本身的地址,所以实例p2调用时,变量值并不会变,而如果类变量类型是可变的,调用他,变量值就会改变但是地址不会变,看下面的例子:

class Person:
    name=[]
p1=Person()
p2=Person()
p1.name.append(1)
print(p1.name)  # [1]
print( p2.name)  # [1]
print( Person.name)  # [1]

4、Python自省
这个也是python彪悍的特性.
自省就是面向对象的语言所写的程序在运行时,所能知道对象的类型.简单一句就是运行时能够获得对象的类型.不用定义,赋什么类型的值它就会是什么类型的变量,比如type(),dir(),getattr(),hasattr(),isinstance().

a = [1,2,3]
b = {'a':1,'b':2,'c':3}
c = True
print(type(a),type(b),type(c))   # <type 'list'> <type 'dict'> <type 'bool'>
print(isinstance(a,list))  # True

相关文章

网友评论

      本文标题:python基础题(1)

      本文链接:https://www.haomeiwen.com/subject/qzvtdqtx.html