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

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

作者头像
用户7886150
修改于 2021-01-25 02:29:22
修改于 2021-01-25 02:29:22
6040
举报
文章被收录于专栏:bit哲学院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 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
python 类
首先super,我们都知道他的意思是继承父类的含义,但是python中继承父类的实现可以直接再括号中写例如ChildA和childB,这两个是一样的
Tim在路上
2020/08/05
1.1K0
Python面试题【BAT版】(02)
今天给大家分享2018年BAT面试过程中的python的相关问题。所有的面试题和答案均来源于网络,如有侵权请及时联系,答案如有不正确还请各位及时指正。为面试而生希望各位都能化身offer收割机。
PM小王
2019/07/02
6640
python学习笔记:第16天 面向对象
目录 ⼀、类的成员介绍: 二、类的成员-变量 三、类的成员-方法 四、类的成员-属性 五、私有属性 ⼀、类的成员介绍: ⾸先, 什么是类的成员. 很简单. 我么能在类中写什么? 写的内容就是成员. 到
py3study
2020/01/19
3540
详解Python类中的三种方法
在Python中定义的类,常用的有三种方法(方法其实就是函数),他们分别是实例方法、类方法和静态方法。他们使用于不同的场景,今天就教大家如何区分并在类中正确的使用他们,达到我们需要的效果。
罗罗攀
2021/07/08
8350
Python3 | 练气期,面向对象、类魔术方法,类修饰器!
如果你接触过 Java、Golang 编程语言,那么你一定知道面向对象编程(OOP)的概念。面向对象编程(OOP)是相对于面向过程编程而言的,面向过程编程是一种以过程为中心的开发模式,而面向对象编程则是以对象为中心的开发模式。
全栈工程师修炼指南
2024/07/29
2190
Python3 | 练气期,面向对象、类魔术方法,类修饰器!
30天拿下Python之面向对象编程
在上一节,我们介绍了Python的函数,包括:函数的定义、函数的调用、参数的传递、lambda函数等内容。在本节中,我们将介绍Python的面向对象编程。面向对象编程(Object-Oriented Programming, 即OOP)是一种编程范型,它以对象为基础,将数据和操作封装在一个类(Class)中。在Python中,类是一种定义对象结构和行为的模板,而对象则是类的实例。类定义了一个新的类型,用于创建具有特定属性和方法的对象。类是面向对象编程的核心,它允许程序员使用对象来组织代码和复用代码。
用户6256742
2024/06/22
910
python面向对象具体解释(上)「建议收藏」
Python 类使用 class 关键字来创建。简单的类的声明能够是关键字后紧跟类名:
全栈程序员站长
2022/07/07
2650
python-静态方法staticmethod、类方法classmethod、属性方法property
Python的方法主要有3个,即静态方法(staticmethod),类方法(classmethod)和实例方法:
狼啸风云
2019/12/19
2.2K0
python super()和classmethod
子类中定义了同父类同名的函数后,需要显示调用父类函数时,可以通过 super,也可以直接通过父类名,建议使用 super,比如在初始化函数中调用父类初始化方法,尤其在多重继承的情况下 看看例子:
orientlu
2018/09/13
8300
Python面试题之Python中的类和实例
类,在学习面向对象我们可以把类当成一种规范,这个思想就我个人的体会,感觉很重要,除了封装的功能外,类作为一种规范,我们自己可以定制的规范,从这个角度来看,在以后我们学习设计模式的时候,对设计模式的理解会很有帮助。其次,语言中类是抽象的模板,用来描述具有相同属性和方法的对象的集合,比如Animal类。而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。
Jetpropelledsnake21
2018/08/10
1.1K0
Python面试题之Python中的类和实例
python之成员(面向对象)
2. 变量   1. 实例变量: 昨天写的就是实力变量, 由对象去访问的变量.   2. 类变量. 此时. 这个变量属于类. 但是对象也可以访问.
py3study
2020/01/20
5890
Python后端技术栈(三)--设计模式
Somewhere, something incredible is waiting to be known.
小闫同学啊
2019/07/18
1.1K0
Python后端技术栈(三)--设计模式
Python面向对象(成员)(二)
        特点: 在声明的时候. 需要给出self, self必须放在第一个位置
py3study
2020/01/22
5940
Python入门之面向对象编程(四)Python描述器详解
本文分为如下部分 引言——用@property批量使用的例子来引出描述器的功能 描述器的基本理论及简单实例 描述器的调用机制 描述器的细节 实例方法、静态方法和类方法的描述器原理 property装饰器的原理 描述器的应用 参考资料 引言 前面python面向对象的文章中我们讲到过,我们可以用@property装饰器将方法包装成属性,这样的属性,相比于其他属性有一个优点就是可以在对属性赋值时,进行变量检查,举例代码如下、 class A: def __init__(self, name, sco
Jetpropelledsnake21
2018/05/02
8810
[887]python中@classmethod和@staticmethod
一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法。 而使用@staticmethod或@classmethod,就可以不需要实例化,**直接类名.方法名()**来调用。 这有利于组织代码,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁。
周小董
2020/08/11
3560
Python:类方法、实例方法与静态方法深度解析(补)
今天看程序时,发现自己好像忘了这三者的区别,所以重新写了一篇深度解析,希望之前看博客没看懂的小伙伴可以通过这个博客分清楚这三个方法。跟的是麦叔的课,不是自己的代码!
Pocker_Spades_A
2024/12/24
1680
Python:类方法、实例方法与静态方法深度解析(补)
Python面向对象基础
当把number属性变成私有属性__number之后,无法直接访问得到,只能通过get_number和set_number两个函数访问__number属性。
职场亮哥
2020/10/10
1.1K0
Python面向对象基础
每日一道python面试题 - Python的实例,类和静态方法揭秘
注意:对于Python 2用户:@staticmethod和@classmethod装饰器自Python 2.4起可用,此示例将按原样工作。class MyClass:您可以选择声明一个继承自object该class MyClass(object):语法的新样式类,而不是使用简单的声明。除此之外,您还不错。
公众号---人生代码
2020/05/16
1.1K0
Python面向对象基础
NOTE: 重要强调:     Python的作用域和命名空间 (1)命名空间 是从命名到对象的映射     ①内置命名空间     ②全局命名空间:模块     ③本地命名空间:模块中的函数和类 (2)作用域   是一个 Python 程序可以直接访问命名空间的正文区域 一:简介             类:用来描述具有相同的属性和方法的对象的集合         方法:类中定义的函数       类变量:类变量在整个实例化的对象中是公用的。                     类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。     实例变量:定义在方法中的变量,只作用于当前实例的类。(注意区分实例变量和类变量)     实例变量用于对每一个实例都是唯一的数据,类变量用于类的所有实例共享的属性和方法     用构造方法初始化的属性叫做实例变量,直接在类中定义的属性叫做类变量。    方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override)        实例化:创建一个类的实例,类的具体对象            对象:通过类定义的数据结构实例     二:语法格式     class ClassName:             <statement-1>             <statement-N> 三:类对象     类对象支持两种操作:属性引用和实例化。     (1)类对象创建后,类命名空间中所有的命名都是有效属性名MyClass.f     (2)实例化:将类对象看作是一个返回新的类实例的无参数函数x = MyClass() 四:类属性     公有属性:在类中定义,可以在类间调用,可以通过析构函数进行初始化     私有属性:在类中定义,以双下划线开始,在类外不能被直接调用,只能被类内部方法使用!     调用方法:用公有方法返回! 五:类方法     (1)类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称,     按照惯例它的名称是 self     (2)在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,     类方法必须包含参数 self, 且为第一个参数,self 代表的是类的实例     (3)两个下划线开头,声明该方法为私有方法,只能在类的内部调用 ,不能在类地外部调用     (4)类的专有方法 六:构造函数     类有一个名为 __init__() 的特殊方法(构造方法),     该方法在类实例化时会自动调用类有一个名为 __init__() 的特殊方法(构造方法),     该方法在类实例化时会自动调用     可以声明带默认参数的实例变量! 七:析构函数     实例化的对象调用结束时候调用! 八:类的继承         (1)语法结构         class DerivedClassName(BaseClassName1):                     <statement-1>                     .                     <statement-N>         (2)多类继承的时候,新式类(python3)按照广度优先的原则,         (找一个爸爸,再找下一个爸爸。。。。)         class DerivedClassName(Base1, Base2, Base3):                 <statement-1>                 .                     <statement-N>     (3)基类名与派生类定义在同一个作用域中,除了类,还可以用表达式,     基类定义在另一个模块中时这一点非常有用:         class DerivedClassName(modname.BaseClassName):     这种写法在模块化程序中很重要!     (4)方法重写     ①父类方法的功能不能满足你的需求,可以在子类重写你父类的方法         super(Child,c).myMethod() #用子类对象调用父类已被覆盖的方法           子类,对象, 方法     ②派生类对基类的方法重写,重写后的基类方法叫做费捆绑方法,     不能直接调用,需要使用super函数。     注意:     ①子类不重写 __init__,实例化子类时,会自动调用父类定义的 __init__。     ②重写了__init__ 时,实例化子类,就不会调用父类已经定义的 __init__     ③如果重写了__init__ 时,要继承父类的构造方法,
py3study
2020/01/19
4950
面试题目及答案
1 Python的函数参数传递 看两个例子: a = 1 def fun(a): a = 2 fun(a) print a # 1 a = [] def fun(a): a.append(1) fun(a) print a # [1] 所有的变量都可以理解是内存中一个对象的“引用”,或者,也可以看似c中void*的感觉。 通过id来看引用a的内存地址可以比较理解: a = 1 def fun(a): print "func_in",id(a) # func_in 413224
zhang_derek
2018/04/11
4.3K0
面试题目及答案
相关推荐
python 类
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档