实例属性是对于每个实例都独有的数据,实例属性每个实例各自拥有,互相独立
类属性是该类所有实例共享的属性和方法,类属性有且只有一份。
———可以用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,类定义时;
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
参考文章