Python 类属性,实例属性,类方法,实例方法,静态方法,属性绑定,属性引用

类属性,实例属性

实例属性是对于每个实例都独有的数据,实例属性每个实例各自拥有,互相独立
类属性是该类所有实例共享的属性和方法,类属性有且只有一份。
———可以用Object.dict或者dir(Object)两种方式查看对象有哪些属性

class Dog(object):
    food = "gutou" #类属性
    age = "1"      #类属性

    def __init__(self, name):
        self.NAME = name   #NAME定义的是实例属性,通过(类名.)的方式无法访问
    def f(self):     #实例方法,(类名.) 无法访问,里面的self参数指某个实例本身
        print("1")
    @classmethod         #这里通过加@classmethod,说明下面方法是类方法,那么比如
              #eat(self,age)里面self即指类Dog本身,这里可以换成cls
    def eat(self,age): #只能是类中的变量
        # print(self.NAME)
        print(age)     #这个age只是输出传进来的形参,并不是实例属性或者类属性
        print(self.food) #因为self指Dog本身,所以self.food即为Dog.food ,
#访问的是类属性

    @classmethod
    def eat1(cls):  # 同上,这里是将self换成了cls,不影响
        # print(self.NAME)
        cls.age = "10"    #注意,因为访问的是类属性,所以必须得访问类有的属性
#比如访问cls.fur 那就报错了
        cls.food = "tang"

    @staticmethod         #传说中的静态方法!!可以直接通过(类名.)或者(实例.)的方式访问
    def print_1():
        print(Dog.food, Dog.age)

方法的访问方式

   
  类方法可以通过(类名.)访问,也可以通过(实例.)访问,通过(实例.)方式访问的时候,底层其实也是通过寻找实例所属的类,然后通过(类名.)的方式访问的。
  实例方法只能通过(实例.)的方式访问了!!
  静态方法可以通过(类名.)或者(实例.)的方式访问
  参数传递上的区别,实例方法悄悄传递的是self引用作为参数,而类方法悄悄传递的是cls引用作为参数。

属性绑定

属性绑定分为1,类属性绑定;2,实例属性绑定

其实我感觉属性绑定意思是说 定义一个属性,并且 它是属于类还是实例

  1. 类属性绑定:

            1,类定义时;
            2,运行时任意阶段。
    

    1.1例子 

class Dog(object):
    food = "gutou" #类属性
    age = "1"      #类属性

 
这里,food,age就是在类定义的时候就绑定给类了

1.2例子

Dog.counry="China"  #随时添加新属性
print("Dog.country:",Dog.counry)   #输出Dog.country: China
del Dog.counry  #删除属性
print("Dog.country:",Dog.counry) #报错type object 'Dog' has no attribute 'counry'

2. 实例属性绑定:

            1,实例初始化(__init__)时;
            2,运行时任意阶段。

2.1例子

d1=Dog("d1")
d2=Dog("d2")
print(d1.NAME)  #d1
print(d2.NAME)  #d2

2.2例子

d1=Dog("d1")
d2=Dog("d2")
d1.fur="red"
print("d1.fur :",d1.fur)         #d1.fur : red
print("d1.dict: ",d1.__dict__)   #d1.dict:  {'fur': 'red', 'NAME': 'd1'}
print("d2.dict: ",d2.__dict__)   #d2.dict:  {'NAME': 'd2'}

可以看出,在运行中给d1添加了fur属性

属性引用

看代码看代码

d1=Dog("d1")
d2=Dog("d2")
print(d1.age)     1
print(d2.age)     1
print(Dog.age)    1
Dog.age="10000"
print(d1.age)     10000
print(d2.age)     10000
print(Dog.age)    10000
d1.age="20000"
print(d1.age)     20000    #问题来了!!!!!
print(d2.age)     10000
print(Dog.age)    10000

如图,问题来了,age属性是类属性,按道理讲,d1改了age值,那么通过Dog或者d2访问的age都应该改变啊,但是只有d1自己的age属性变了。。。这就是属性引用!!!

其实,d1.age=”20000”导致d1对象里增加了一个新的属性age,并且赋值为20000,当实例属性和类属性同名时,总是先到实例对象中查找属性,再到类属性中查找属性;

注:并不是说把类属性age绑定为实例属性and类里就没有age属性了。。。。)

不信的话,可以这么查看:

#查看d1,d2有哪些属性
print("d1.__dict__ :" ,d1.__dict__)
#输出d1.__dict__ : {'NAME': 'd1', 'age': '20000'}
print("d2.__dict__ :" ,d2.__dict__)
#输出d2.__dict__ : {'NAME': 'd2'}

可以发现d1多了一个age属性~
!!!!!所以此时Dog类有age,food属性,d1有age,NAME属性,d2有NAME属性!!!!!


又发现一个python里的私有属性

class Person(object):
    __count = 0             #__count是私有类属性
    def __init__(self, name,country):
        self.name = name
       self.__country=country    #__country是私有实例属性
p= Person('Bob')

那么继续

try:
    print(Person.__count)  #AttributeError: type object 'Person4' has no attribute '__count'
except AttributeError:
    print('AttributeError')

或者

try:
    print(p.__country)  #AttributeError: 'Person1' object has no attribute '__country'
except AttributeError:
    print('AttributeError')

虽然私有属性无法从内部访问,但是可以设置getter方法

class Person6(object):
    def __init__(self, name, score):
        self.name = name
        self.__score = score
    def get_grade(self):
        if self.__score >= 80:
            return "A-Excellent"
        elif self.__score >= 60:
            return "B-Passed"
        return "C-Failed"
p6_1 = Person6('Bob', 89)
p6_2 = Person6('Alice', 69)
p6_3 = Person6('Tim', 59)
print(p6_1.get_grade())     #A-Excellent
print(p6_2.get_grade())     #B-Passed
print(p6_3.get_grade())     #C-Failed

参考文章

你可能感兴趣的:(python)