MyException - 我的异常网
当前位置:我的异常网» Perl/Python » 静态方法、类方法、属性步骤

静态方法、类方法、属性步骤

www.MyException.Cn  网友分享于:2013-08-11  浏览:0次
静态方法、类方法、属性方法

一、静态方法

 1.1、定义

   在类中的方法前面通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法

class Person(object):

    def __init__(self, name):
        self.name = name

    @staticmethod
    def speak():
        print('someone is speaking chinese.')

# 静态方法在类中也不需要传入 self参数

  

1.2、静态方法的特性

  静态方法是不能访问实例变量和类变量的 

class Person(object):

    def __init__(self, name):
        self.name = name

    @staticmethod
    def speak(self):
        print('%s is speaking chinese.' % self.name)

p = Person('Bigberg')
p.speak()


# 我们在 speak(self) 函数中传入 self

  事实上以上代码运行会出错的,说speak 需要一个self参数,但调用时却没有传递,没错,当speak变成静态方法后,再通过实例调用时就不会自动把实例本身当作一个参数传给self了。  

Traceback (most recent call last):
  File "G:/python/untitled/study6/静态方法.py", line 26, in <module>
    p.speak()
TypeError: speak() missing 1 required positional argument: 'self'

  想让以上代码可以正常执行,有两种方法:

  1. 在调用时将实例本身传给 speak() 
class Person(object):

    def __init__(self, name):
        self.name = name

    @staticmethod
    def speak(self):
        print('%s is speaking chinese.' % self.name)

p = Person('Bigberg')
p.speak(p)

# 输出

Bigberg is speaking chinese.

  2.在方法speak中去掉self,但这也意味着,在eat中不能通过self.调用实例中的其它变量了 

class Person(object):

    def __init__(self, name):
        self.name = name

    @staticmethod
    def speak():                # 方法中已经没有 self 参数了
        print('%s is speaking chinese.' % 'anyone')

p = Person('Bigberg')
p.speak()


#输出
anyone is speaking chinese.

  

1.3 总结

  普通的方法,可以在实例化后直接调用,并且在方法里可以通过self.调用实例变量或类变量,但静态方法是不可以访问实例变量或类变量的,一个不能访问实例变量和类变量的方法,其实相当于跟类本身已经没什么关系了,它与类唯一的关联就是需要通过类名来调用这个方法。

 

二、类方法

  2.1、定义

  类方法通过@classmethod装饰器实现,类方法和普通方法的区别是, 类方法只能访问类变量,不能访问实例变量

  2.2、访问实例变量

        直接访问实例变量会报错,没有该属性  

class Person(object):

    def __init__(self, name, country):
        self.name = name
        self.country = country

    @classmethod
    def nationality(self):
        print('Bigberg is %s.' % self.country)

p = Person('Bigberg', 'CN')
p.nationality()

# 输出
Traceback (most recent call last):
  File "G:/python/untitled/study6/静态方法.py", line 31, in <module>
    p.nationality()
  File "G:/python/untitled/study6/静态方法.py", line 24, in nationality
    print('Bigberg is %s.' % self.country)
AttributeError: type object 'Person' has no attribute 'country'

# 提示没有一个 country 属性  

  2.3、访问类变量,即 全局属性/静态字段 

class Person(object):

    country = 'Chinese'    # 增加一个 全局属性/静态字段

    def __init__(self, name, country):

        self.name = name
        self.country = country

    @classmethod
    def nationality(cls):    # 这里将sefl 改为 cls
        print('Bigberg is %s.' % cls.country)

p = Person('Bigberg', 'CN')
p.nationality()

# 输出
Bigberg is Chinese.

 

三、属性方法 

   3.1、定义

  属性方法的作用就是通过@property把一个方法变成一个静态属性 

class Person(object):

    country = 'Chinese'

    def __init__(self, name, country):

        self.name = name
        self.country = country

    @property
    def drive(self):
        print('%s is driving a car.' % self.name)
p = Person('Bigberg', 'CN')
p.drive()
# 输出 
Traceback (most recent call last): Bigberg is driving a car. File "G:/python/untitled/study6/静态方法.py", line 38, in <module> p.drive() TypeError: 'NoneType' object is not callable

  调用会出错误, 说NoneType is not callable, 因为eat此时已经变成一个静态属性了, 不是方法了, 想调用已经不需要加()号了,直接p.drive就可以了

  正常调用: 

p = Person('Bigberg', 'CN')
p.drive

# 输出

Bigberg is driving a car.

  

  3.2 setter用法

  如果我们想在属性方法里传参,比如车的品牌,我们就要用setter了,具体用法  @属性方法名.setter 

class Person(object):

    country = 'Chinese'

    def __init__(self, name, country):

        self.name = name
        self.country = country
        self.car = "LAMBORGHINI"   # 定义车品牌为兰博基尼

    @property
    def drive(self):
        print('%s is driving a %s.' % (self.name, self.car))

p = Person('Bigberg', 'CN')
p.drive

# 输出
Bigberg is driving a LAMBORGHINI.

  很显然我们开出去的车就是兰博基尼,如果我们想自己传入车品牌呢?比如 特斯拉: 

class Person(object):

    country = 'Chinese'

    def __init__(self, name, country):

        self.name = name
        self.country = country
        self.car = "LAMBORGHINI"   #当然这里也可以设置为私有属性

    @property
    def drive(self):  # 这里不能传参是因为调用的时候,p.drive 没有()了,不能传入
        print('%s is driving a %s.' % (self.name, self.car))

    @drive.setter     # 修饰方法drive,可以为属性赋值
    def drive(self, car):     # 我们要重新定义这个drive方法
        print("set car:", car)
        self.car = car

p = Person('Bigberg', 'CN')
p.drive = 'Tesla'     # 给属性赋值
p.drive

#输出

set car: Tesla
Bigberg is driving a Tesla.

  3.3 deleter 用法

  用来删除属性方法,具体用法 @属性方法名.deleter  

# 以上例
# 我们可以发现普通属性是可以通过del直接删除的
# 比如
print(p.name)
del p.name
print(p.name)

# 输出

Traceback (most recent call last):
Bigberg
  File "G:/python/untitled/study6/静态方法.py", line 49, in <module>
    print(p.name)
AttributeError: 'Person' object has no attribute 'name'

#删除之后就不能再调用了

  但是我们用del p.drive这种方法来删除属性方法是行不通的:

del p.drive

#输出
Traceback (most recent call last):
  File "G:/python/untitled/study6/静态方法.py", line 51, in <module>
    del p.drive
AttributeError: can't delete attribute

  所以我们就要用到 deleter方法: 

class Person(object):

    country = 'Chinese'

    def __init__(self, name, country):

        self.name = name
        self.country = country
        self.car = "LAMBORGHINI"

    @property
    def drive(self):
        print('%s is driving a %s.' % (self.name, self.car))

    @drive.setter
    def drive(self, car):
        print("set car:", car)
        self.car = car

    @drive.deleter   # 修饰 drive 方法,可以删除属性
    def drive(self):   # 重新定义 drive方法
        del self.car    #  删除的是属性
        print("扣了你的车,让你开豪车...")

p.drive = 'Tesla'
p.drive

del p.drive   

# 输出
set car: Tesla
Bigberg is driving a Tesla.
扣了你的车,让你开豪车...

  让我们在秋名山再开一次车...

p.drive

# 输出
扣了你的车,让你开豪车...
Traceback (most recent call last):
  File "G:/python/untitled/study6/静态方法.py", line 57, in <module>
    p.drive
  File "G:/python/untitled/study6/静态方法.py", line 28, in drive
    print('%s is driving a %s.' % (self.name, self.car))
AttributeError: 'Person' object has no attribute 'car'

# 提示没有这个属性了

 

四、属性方法应用场景

你想知道一个航班当前的状态,是到达了、延迟了、取消了、还是已经飞走了, 想知道这种状态你必须经历以下几步:

1. 连接航空公司API查询

2. 对查询结果进行解析 

3. 返回结果给你的用户

因此这个status属性的值是一系列动作后才得到的结果,所以你每次调用时,其实它都要经过一系列的动作才返回你结果,但这些动作过程不需要用户关心,用户只要知道结果就行

class Flight(object):

    def __init__(self, name):
        self.name = name

    def check_status(self):
        print("checking flight %s status" % self.name)
        return 1

    @property
    def flight_status(self):
        status = self.check_status()
        if status == 0:
            print("flight got canceled...")

        elif status == 1:
            print("flight is arrived...")

        elif status == 2:
            print("flight has departured already...")

        else:
            print("cannot confirm the flight status")

    @flight_status.setter
    def flight_status(self, status):
        status_dic = {
            0: "canceled",
            1: "arrived",
            2: "departured"
        }
        print("\033[31;1mHas changed the flight status to \033[0m", status_dic.get(status))

    @flight_status.deleter  # 删除
    def flight_status(self):
        print("status got removed...")

f = Flight('CA980')
f.flight_status
f.flight_status = 2

#输出

checking flight CA980 status
flight is arrived...
Has changed the flight status to  departured

  

五、总结

  1.  静态方法是不可以访问实例变量或类变量的
  2. 类方法和普通方法的区别是, 类方法只能访问类变量,不能访问实例变量
  3. 属性方法将一个方法变为类的属性,调用时不需要加()。有@property 、@属性方法名.setter、@属性方法名.deleter 三种装饰方法

文章评论

一个程序员的时间管理
一个程序员的时间管理
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
中美印日四国程序员比较
中美印日四国程序员比较
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
 程序员的样子
程序员的样子
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
程序员和编码员之间的区别
程序员和编码员之间的区别
如何成为一名黑客
如何成为一名黑客
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
10个调试和排错的小建议
10个调试和排错的小建议
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
程序员的鄙视链
程序员的鄙视链
为什么程序员都是夜猫子
为什么程序员都是夜猫子
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
旅行,写作,编程
旅行,写作,编程
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
老程序员的下场
老程序员的下场
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
漫画:程序员的工作
漫画:程序员的工作
那些争议最大的编程观点
那些争议最大的编程观点
代码女神横空出世
代码女神横空出世
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
编程语言是女人
编程语言是女人
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
Java程序员必看电影
Java程序员必看电影
总结2014中国互联网十大段子
总结2014中国互联网十大段子
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
每天工作4小时的程序员
每天工作4小时的程序员
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
鲜为人知的编程真相
鲜为人知的编程真相
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有