python3 中定义类函数参数中加 self 和不加的区别在哪?

2016-02-25 18:33:27 +08:00
 dsp2138

class A:
def fun():
pass


class B:
def fun1(self):
pass

这两个类中各定义了一个函数,其中 B 中 fun1 有 self,而 A 无!
当然这段函数应该是在 python3 版本下的情况!
具体有什么区别吗,
加上 self 后指代的是实例,不加就是类方法?
那么:
class A1:
@classmethod
def fun():
pass
这里的函数和 A 中的函数有什么区别呢?

请大虾赐教!
谢谢

12407 次点击
所在节点    Python
11 条回复
zangxixi
2016-02-25 20:54:27 +08:00
class A:
def fun():
pass
# 这种就是静态函数,一般用装饰器 @staticmethod 修饰
class B:
def fun1(self):
pass
# 这种就是成员函数,类实例可以直接调用
@classmethod
def fun():
pass
# 这种是类函数,要求第一个参数表示类( cls )。也就是说,除了装饰器 @classmethod 外,还要求它的定义如 def fun(cls,...)。这是通过类直接调用的,如 A1.fun(...)
昨天也碰到了相同的问题,我在 notebook 里面有些:
zangxixi
2016-02-25 20:55:49 +08:00
dsp2138
2016-02-25 21:47:30 +08:00
@zangxixi

@classmethod 装饰器和 staticmethod 装饰器修饰的函数,都可以不用实例化访问,
成员函数只能是实例化对象可以访问,类本身是无法访问的!
不加 self 的类函数和 staticmethod 是一样的,也就是说在类外部定义这个函数是一个样吗?

另外, staticmethod 和 classmethod,使用这两个装饰器的好处是什么呢?具体用到何处,何时使用比较好呢?
dsp2138
2016-02-25 21:50:20 +08:00
@zangxixi
抱歉,菜鸟一个大洋西海岸的高大上的东网站西没法看啊!
github 好久都没访问过了,我这里很多都访问不了!
百度云, 360 云等等云分享的内容, csdn 的 blog 。。。
---
能不能说下怎么方便的上 github 呢
谢谢
dqh3000
2016-02-25 23:11:57 +08:00
其实 self 这个设定,从函数式语言的角度理解就很好理解了
harry890829
2016-02-25 23:22:46 +08:00
@dsp2138 github 本身应该是没有被墙的,你换 dns 试试看
dsp2138
2016-02-26 00:19:08 +08:00
@harry890829
是吗?
我这里是新疆电信
是了几个都不行

能把你现在用的 dns 地址分享下吗
harry890829
2016-02-26 09:10:39 +08:00
@dsp2138 新疆那边好像有点特殊……这个不了解,上海电信和上海联通一般用运营商的 dns 就可以,偶尔需要使用 opendns , 208.67.222.222 208.67.220.220 ,你可以试试看
zangxixi
2016-02-26 09:37:14 +08:00
zangxixi
2016-02-26 09:38:26 +08:00
@dsp2138 我把 notebook 里面相关内容贴出来了,你感受一下:
# 静态函数,类函数,成员函数
# 静态函数(@staticmethod): 即静态方法,主要处理与这个类的逻辑关联, 如验证数据;
# 类函数(@classmethod):即类方法, 更关注于从类中调用方法, 而不是在实例中调用方法, 如构造重载;
# 成员函数: 实例的方法, 只能通过实例进行调用;
class Person:
grade=1
def __init__(self,name):
self.name = name

def sayHi(self):#加 self 区别于普通函数
print 'Hello, your name is?',self.name

# 声明静态,去掉则编译报错;还有静态方法不能访问类变量和实例变量
# 好处:不需要定义实例即可使用这个方法。另外,多个实例共享此静态方法。
@staticmethod
def sayName():#使用了静态方法,则不能再使用 self
print "my name is king"#,grade,#self.name

# 类方法:一个类方法就可以通过类或它的实例来调用的方法,
# 不管你是用类来调用这个方法还是类实例调用这个方法,该方法的第一个参数总是定义该方法的类对象。
@classmethod
def classMethod(cls):
print("class method")
lonelinsky
2016-02-26 10:23:14 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/259129

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX