前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python类三种方法,函数传参,类与实例变量(一)

Python类三种方法,函数传参,类与实例变量(一)

作者头像
用户7886150
修改2021-01-25 10:29:22
5540
修改2021-01-25 10:29:22
举报
文章被收录于专栏:bit哲学院

参考链接: Python staticmethod()

1 Python的函数传递: 

首先所有的变量都可以理解为内存中一个对象的‘引用’ 

a = 1

def func(a):

    a = 2

func(a)

print(a) # 1

a = 1

def fun(a):

    print("函数里",id(a))   # 函数里 41322472

    a = 2

    print("赋值后",id(a), id(2))   # 赋值后 41322448 41322448

print("函数外",id(a), id(1))  # 函数外 41322472 41322472

fun(a)

print(a)  # 1 

可以看到,在执行完a = 2之后,a引用中保存的值,即内存地址发生变化,由原来1对象的所在的地址变成了2这个实体对象的内存地址。下面我们来看另一个例子: 

a = []

def fun(a):

    a.append(1)

fun(a)

print a  # [1]

a = []

def fun(a):

    print("函数里",id(a))  # 函数里 53629256

    a.append(1)

print("函数外",id(a))     # 函数外 53629256

fun(a)

print(a) # [1] 

注意: 

类型是属于对象的,而不是变量。而对象有两种,“可更改”(mutable)与“不可更改”(immutable)对象。strings, tuples, 和numbers是不可更改的对象,而 list, dict, set 等则是可修改的对象。当一个引用传递给函数的时候,函数自动复制一份引用,这个函数里的引用和外边的引用没有半毛关系了.所以第一个例子里函数把引用指向了一个不可变对象number,当函数返回的时候,外面的引用没半毛感觉.而第二个例子就不一样了,函数内的引用指向的是可变对象list,指向了列表的内存地址,因此调用并不会改变list内存地址. 

2 python中元类 

Python中的类也是对象。元类就是用来创建这些类(对象)的,元类就是类的类  

MyClass = MetaClass()    #元类创建

MyObject = MyClass()     #类创建实例

实际上MyClass就是通过type()来创建出MyClass类,它是type()类的一个实例;同时MyClass本身也是类,也可以创建出自己的实例,这里就是MyObject 

类就是创建类这种对象的东西, type就是Python的内建元类,当然了,你也可以创建自己的元类。  

age = 35

age.__class__

#输出:<type 'int'>

name = 'bob'

name.__class__

#输出:<type 'str'>

def foo(): 

    pass

foo.__class__

#输出:<type 'function'>

class Bar(object): 

    pass

b = Bar()

b.__class__

#输出:<class '__main__.Bar'>

对于任何一个__class__的__class__属性又是什么呢?

a.__class__.__class__

#输出:<type 'type'>

age.__class__.__class__

#输出:<type 'type'>

foo.__class__.__class__

#输出:<type 'type'>

b.__class__.__class__

#输出:<type 'type'> 

3 静态方法(@staticmethod)和类方法(@classmethod) 

Python其实有3个方法,即静态方法(staticmethod),类方法(classmethod)和实例方法 

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是对实例或者类的绑定 

对于一般的函数来说我们可以这么调用foo(x),这个函数就是最常用的,它的工作跟任何东西(类,实例)无关.对于实例方法,我们知道在类里每次定义方法的时候都需要绑定这个实例,就是foo(self, x),因为实例方法的调用离不开实例,我们需要把实例自己传给函数,调用的时候是这样的a.foo(x)(其实是foo(a, x)).类方法一样,只不过它传递的是类而不是实例,A.class_foo(x).注意这里的self和cls可以替换别的参数,但是python的约定是这俩对于静态方法其实和普通的方法一样,不需要对谁进行绑定,唯一的区别是调用的时候需要使用a.static_foo(x)或者A.static_foo(x)来调用.不管是 类调用,还是实例调用静态方法,都是指向同一个函数对象  

#实例方法类方法静态方法a = A()a.foo(x)a.class_foo(x)a.static_foo(x)A不可用A.class_foo(x)A.static_foo(x) 

4 类变量与实例变量 

类变量 : 是可在类的所有实例之间共享的值(也就是说,它们不是单独分配给每个实例的)。 

实例变量 : 实例化之后,每个实例单独拥有的变量。 

class Test(object):  

    num_of_instance = 0  #类变量

    def __init__(self, name):   #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  类名.属性 

这里p1.name="bbb"是实例调用了类变量,,类似函数传参的问题,p1.name一开始是指向的类变量name="aaa",但是在实例的作用域里把类变量的引用改变了,就变成了一个实例变量,self.name不再引用Person的类变量name了。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档