python中的@staticmethod和@classmethod区别(整理)

问题:Python中 @staticmethod@classmethod 两种装饰器装饰的函数有什么不同?
原地址http://stackoverflow.com/questions/136097/what-is-the-difference-between-staticmethod-and-classmethod-in-python


Python其实有3类方法:

  • 静态方法(staticmethod)
  • 类方法(classmethod)
  • 实例方法(instance method)

看一下下面的示例代码:

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()来调用。

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

那么对于类方法和静态方法都可以不实例对象来调用,那两者的区别又有哪些呢?

从它们的使用上来看

  • @staticmethod 不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。
  • @classmethod 也不需要self参数,但第一个参数需要是表示自身类的cls参数。

如果在@staticmethod中要调用到这个类的一些属性方法,只能直接 类名.属性名类名.方法名

而@classmethod因为持有 cls 参数,可以来调用类的属性,类的方法,实例化对象等,避免硬编码。

代码:

class A(object):
    bar = 1
    def foo(self):
        print 'foo'
 
    @staticmethod
    def static_foo():
        print 'static_foo'
        print A.bar
 
    @classmethod
    def class_foo(cls):
        print 'class_foo'
        print cls.bar
        cls().foo()
 
A.static_foo()
A.class_foo()
输出
static_foo
1

class_foo
1
foo

摘自:
https://www.cnblogs.com/taceywong/p/5813166.html
https://blog.csdn.net/handsomekang/article/details/9615239

mac下安装python web框架django

前提

由于mac自带的python2.7(路径 /usr/bin/python)
后来手动又安装了python3.7(/usr/local/bin/python3)

两个版本共存。为了方便,直接在.zshrc文件里做了别名映射

alias python="/usr/local/bin/python3.7"

所以直接使用命令python实际上用的是3.7版本。

按照官方教程 https://docs.djangoproject.com/zh-hans/2.1/intro/install/ 安装django。发现在使用命令 pip install django 安装后发现检测不到django,很奇怪,后来发现了问题所在。

➜  ~ python
Python 3.7.1 (default, Nov  6 2018, 18:46:03)
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
Traceback (most recent call last):
  File "", line 1, in 
ModuleNotFoundError: No module named 'django'

原来python2对应一个是包安装命令是 pip,而python3对应的是一个叫做pip3的命令。所以使用新的命令

pip3 install django

安装成功。

➜  ~ python
Python 3.7.1 (default, Nov  6 2018, 18:46:03)
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
>>> print(django.get_version())
2.1.3

解决mac下brew link python3出错brew Error: Permission denied @ dir_s_mkdir – /usr/local/Frameworks

mac上默认的python版本为2.7.10版本,需要升级到python3 版本,通过brew升级

$brew install python3

提示错误

$ brew install python3 Warning: python3 3.6.3 is already installed, it‘s just not linked. You can use `brew link python3` to link this version. $ brew link python3 Linking /usr/local/Cellar/python3/3.6.3… Error: Permission denied @ dir_s_mkdir

发现/usr/local/下没有路径/usr/local/Frameworks
需要新建该路径,并修改权限

解决:

$ sudo mkdir /usr/local/Frameworks
$ sudo chown $(whoami):admin /usr/local/Frameworks

成功:

$ brew link python3
Linking /usr/local/Cellar/python3/3.6.3... 1 symlinks created

参考:
https://github.com/Homebrew/homebrew-core/issues/19286

centos下更新Python版本的步骤

准备安装gitlab,发现系统目前的python版本为2.4.3版本.太低了, 虽然目前最高版本为3.3.0版本.但gitlab不支持这个版本.没有办法,我们这里将python升级到2.7.6版本.

更新python千万不要把老版本的删除!新老版本是可以共存的,很多基本的命令、软件包都要依赖预装的老版本python的,比如yum。

Continue reading