Python 面向对象基础(二)

类属性与方法

类的私有属性

__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时self.__private_attrs

class JustCounter:
    __secretCount = 0  # 类的私有变量
    publicCount = 0  # 类的公开变量
    def __init__(self,value):
        self. __secretCount=value  #优先用类变量
    def count(self):
        self.__secretCount += 1  # 实例的私有变量
        self.publicCount += 1   # 实例的公开变量
        print(self.__secretCount)
    def tell(self,value):
        '''如果又要允许外部代码修改私有属性怎么办?可以用方法实现'''
        self.__secretCount=value
        self.tell=self.__secretCount

counter = JustCounter(1000)
counter.count()
counter.count()
print(counter.publicCount)

counter.tell(1000) #赋值私有变量
print(counter.tell)#访问私有变量
#print(counter.__secretCount)
# 报错,实例不能访问私有变量


#不能直接访问__secretCount是因为Python解释器对外把变量改成了_JustCounter__secretCount,
# 所以,仍然可以通过_JustCounter__secretCount来访问__secretCount变量:
print(counter._JustCounter__secretCount)

 

类的方法

在类的内部,使用 def 关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数( 只能访问类变量 )

#只能访问类变量
#通常将参数名命名为 cls
class Cat(object):
    name = 'lin'
    def __init__(self,name):
        self.name

    @classmethod
    def eat(cls):
        print(' is eating %s'%cls.name)

c=Cat('Kim')
c.eat()
Cat.eat()

--------
 is eating lin
 is eating lin

 

类的私有方法

__private_method:两个下划线开头,声明该方法为私有方法,不能在类地外部调用。在类的内部调用self.__private_methods

class JustCounter:
    def __init__(self,name):
        self.name=name
    def count(self,count):
        '''可以内部方法调用'''
        self.__tell(count)
    def __tell(self,sum):
        '''私有方法不能外部调用'''
        print('%s tell id %s'%(self.name,sum))
counter = JustCounter('Tim')
counter.count(2900)
#counter._tell()#直接调用出错


--------
Tim tell id 2900

 

静态方法

静态方法是一种普通函数,就位于类定义的命名空间中,它不会对任何实例类型进行操作。使用装饰器@staticmethod定义静态方法。类对象和实例都可以调用静态方法:

#名义上归类管理
#时间在静态方法里面方法访问不了类或者实例中属性
class Dog(object):
    def __init__(self,name):
        self.name=name
    @staticmethod#实际上和类没有什么关系
    def eat(self):#一个普通方法不能通过类或者实例直接调用
        print(' is eating %s'%self.name)

d=Dog('Juan')
d.eat(d)
Dog.eat(d)
#d.eat()#实例调用出错

--------
 is eating Juan
 is eating Juan

python中方法也是属性

我们在 class 中定义的实例方法其实也是属性,它实际上是一个函数对象(一切皆对象):

把一个函数变成类方法

# /usr/bin/env python
# coding:utf-8

import types
#普通函数可以传入参数
def fn_get_grade(self):
    if self.score >= 80:
        return 'A'
    if self.score >= 60:
        return 'B'
    return 'C'


#定义一个类
class Person(object):
    score=100
    def __init__(self, name, score):
        self.name = name
        self.score = score

#创建实例对象
p1 = Person('Bob', 90)

print(fn_get_grade)#函数
print(fn_get_grade(p1))#函数传入实例作为参数
#把一个函数变成一个实例方法
p1.get_grade = types.MethodType(fn_get_grade, p1)#实例化属性赋值
print(p1.get_grade)
print (p1.get_grade())

p2 = Person('Alice',50)
print( p2.get_grade())

# ERROR: AttributeError: 'Person' object has no attribute 'get_grade'
# 因为p2实例并没有绑定get_grade

-----
<function fn_get_grade at 0x101862e18>
A
<bound method fn_get_grade of <__main__.Person object at 0x101a20908>>
A

 

把一个方法变成一个静态属性,并进行赋值 @property  装饰器

class Cat(object):
    def __init__(self,name):
        self.name=name
        self.__value=None
    @property#静态属性
    def eat(self):
        print('is eating01 %s'%(self.__value))
    @eat.setter#静态属性赋值操作
    def eat(self,value):
        self.__value=value
    @eat.deleter#del执行方法
    def eat(self):
        del self.__value
c=Cat('Kim')

c.eat='chage'  #赋值操作
c.eat

del c.eat

 

单下划线、双下划线、头尾双下划线说明:

  • __foo__: 定义的是特列方法,类似 __init__() 之类的。

  • _foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *

  • __foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。

 

posted @ 2017-09-13 22:02  Ronny_bin  阅读(94)  评论(0)    收藏  举报