我们知道在 python 的类里面可以定义三种类型的方法:
- [python] view plain copy
- print?
- 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()
可以看到, 实例是三种方法都可以调用的, 而类只可以调用两种所以这些方法的使用就是看你是否要让类不需要通过实例来调用方法, 而类方法和静态方法的区别就是你是否要在该方法引导类的属性或者其他类的类方法
看过 flask web development 这本书的同学应该记得这一段代码:
- [python] view plain copy
- print?
- from config import config
- # ...
- config[config_name].init_app(app)
其中 config 是一个字典, 在 config.py 中定义好的, 其键所对的是在 config.py 中定义好的类, 代码如下:
- [python] view plain copy
- print?
- class Config:
- SECRET_KEY = os.environ.get('SECRET_KEY') or 'you will never know'
- SQLALCHEMY_COMMIT_ON_TEARDOWN = True
- FLASKY_MAIL_SUBJECT_PREFIX = '[lulalula]'
- FLASKY_MAIL_SENDER = 'flasky Admin <dengbulieduo@163.com>'
- FLASKY_ADMIN = os.environ.get('FLASKY_ADMIN')
- FLASKY_POSTS_PER_PAGE = 10
- FLASKY_FOLLOWERS_PER_PAGE = 10
- FLASKY_COMMENTS_PER_PAGE = 10
- SQLALCHEMY_RECORD_QUERIES = True
- FLASKY_SLOW_DB_QUERY_TIME = 0.5
- # init_app 函数的函数体为空只是预留一个方法, 方便调用
- @staticmethod
- def init_app(app):
- pass
- # ...
- class ProductionConfig(Config):
- SQLALCHEMY_DATABASE_URI = os.environ.get('DEV_DATABASE_URL') or \
- 'sqlite:///' + os.path.join(basedir, 'data.sqlite')
- @classmethod
- def init_app(cls, app):
- Config.init_app(app)
- import logging
- from logging.handlers import SMTPHandler
- credentials = None
- secure = None
- if getattr(cls, 'MAIL_USERNAME', None) is not None:
- credentials = (cls.MAIL_USERNAME, cls.MAIL_PASSWORD)
- if getattr(cls, 'MAIL_USE_TLS', None):
- secure = ()
- mail_handler = SMTPHandler(
- mailhost=(cls.MAIL_USERNAME, cls.MAIL_PASSWORD),
- fromaddr=cls.FLASKY_MAIL_SENDER,
- toaddrs=[cls.FLASKY_ADMIN],
- subject=cls.FLASKY_MAIL_SUBJECT_PREFIX + 'Application Error',
- credentials=credentials,
- secure=secure)
- mail_handler.setLevel(logging.Error)
- app.logger.addHandler(mail_handler)(Config):
- SQLALCHEMY_DATABASE_URI = os.environ.get('DEV_DATABASE_URL') or \
- 'sqlite:///' + os.path.join(basedir, 'data.sqlite')
- config = {
- 'development': DevelopmentConfig,
- 'testing': TestingConfig,
- 'production': ProductionConfig,
- 'default': DevelopmentConfig
- }
可以知道如果 config_name = 'production'的时候就会调用 ProductionConfig 这个类, 而 ProductionConfig 继承与 Config, 所以有 Config 的所有属性如果只是为了让类调用 init_app 方法, 大可以像 Config 用静态方法, 但是可以看到 init_app 里面调用了很多属性, 所以只能用类方法来实现这样我们就可以理清这三者之间的关系, 和恰当的使用者这三种方法了
来源: http://www.92to.com/bangong/2018/03-26/33481353.html