V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
dsp2138
V2EX  ›  Python

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

  •  
  •   dsp2138 · 2016-02-25 18:33:27 +08:00 · 12445 次点击
    这是一个创建于 3193 天前的主题,其中的信息可能已经有所发展或是发生改变。

    class A:
    def fun():
    pass


    class B:
    def fun1(self):
    pass

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

    请大虾赐教!
    谢谢

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

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

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

    能把你现在用的 dns 地址分享下吗
    harry890829
        8
    harry890829  
       2016-02-26 09:10:39 +08:00
    @dsp2138 新疆那边好像有点特殊……这个不了解,上海电信和上海联通一般用运营商的 dns 就可以,偶尔需要使用 opendns , 208.67.222.222 208.67.220.220 ,你可以试试看
    zangxixi
        9
    zangxixi  
       2016-02-26 09:37:14 +08:00
    zangxixi
        10
    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
        11
    lonelinsky  
       2016-02-26 10:23:14 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2651 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 15:11 · PVG 23:11 · LAX 07:11 · JFK 10:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.