紧接上一篇类的实例:
class person():
tall = 180
def __init__(self,name,age,weight):
self.name = name
self.age = age
self.weight = weight
def infoma(self):
print('%s is %s weights %s'%(self.name,self.age,self.__weight))
person = person('bruce',25,60)
infoma = person.infoma()
一、数据属性
1、在上面的person类中,”tall”、”name”、”age”和”weight “都被称为 类的数据属性,但是它们又分为 类数据属性 和 实例数据属性。
class person(object):
tall = 180
hobbies = []
def __init__(self, name, age,weight):
self.name = name
self.age = age
self.weight = weight
def infoma(self):
print('%s is %s weights %s'%(self.name,self.age,self.weight))
person.hobbies.extend(["football", "woman"]) #类数据属性 属于类本身,可以通过类名进行访问/修改,此处添加"football"、"woman"两个
print("person hobbies list: %s" %person.hobbies )
# class can add class attribute after class defination
person.hobbies2 = ["reading", "jogging", "swimming"] #在类定义之后,可以通过 类名 动态添加 类数据属性,新增的 类属性也被类和所有实例共有
print( "person hobbies2 list: %s" %person.hobbies2 )
print( dir(person))
person hobbies list: ['football', 'woman'] #类数据属性属于类本身,可以通过类名进行访问/修改
person hobbies2 list: ['reading', 'jogging', 'swimming']['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'hobbies', 'hobbies2', 'infoma', 'tall']
Bruce = person("Bruce", 25,60) #实例数据属性 只能通过实例访问
print ("%s is %d years old" %(Bruce.name, Bruce.age) )
Bruce.gender = "male" #在实例生成后,还可以动态添加实例数据属性,但是这些实例数据属性只 属于该实例
print( "%s is %s" %(Bruce.name, Bruce.gender) )
print( dir(Bruce))
Bruce.hobbies.append("C#")
print (Bruce.hobbies)
Bruce is 25 years old #实例数据属性只能通过实例访问Bruce is male #实例数据属性只能通过实例访问
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'gender', 'hobbies', 'hobbies2', 'infoma', 'name', 'tall', 'weight']['football', 'woman', 'C#']
will = person("Will", 27,60)
print( "%s is %d years old" %(will.name, will.age) )
print( dir(will) )
print (will.hobbies)
Will is 27
years old['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'hobbies', 'hobbies2', 'infoma', 'name', 'tall', 'weight']['football', 'woman', 'C#']
ps:通过内建函数dir(),或者访问类的字典属性’_ _dict _ _’这两种方式都可以查看类有哪些属性
对于类数据属性和实例数据属性,可以总结为:
2、特殊的类属性:对于所有的类,都有一组特殊的属性
class person(object):
tall = 180
hobbies = []
def __init__(self, name, age,weight):
self.name = name
self.age = age
self.weight = weight
def infoma(self):
print('%s is %s weights %s'%(self.name,self.age,self.weight))
print(person.__name__)
print(person.__doc__)
print(person.__bases__)
print(person.__dir__)
print(person.__module__)
print(person.__class__)
person
None(<class 'object'>,)
<method '__dir__' of 'object' objects>
__main__
<class 'type'>
3、属性隐藏:类数据属性属于类本身,被所有该类的实例共享;并且,通过实例可以去访问/修改类属性。但是,在通过实例中访问类属性的时候一定要谨慎,因为可能出现属性”隐藏”的情况
Bruce = person("Bruce", 25,180)
print("person.tall is Bruce.tall: ", person.tall is Bruce.tall)
Bruce.tall = 185 #重新赋值或者修改
print( "person.tall is Bruce.tall: ", person.tall is Bruce.tall)
print( person.__dict__)
print( Bruce.__dict__)
del Bruce.tall #再次删除实例的赋值
print("person.tallis Bruce.tall: ", person.tall is Bruce.tall) #person.tall is Bruce.tall为True
person.tall is Bruce.tall: True person.tall is Bruce.tall: False {'__module__': '__main__', 'tall': 180, 'hobbies': [], '__init__':, 'infoma': , '__dict__': , '__weakref__': , '__doc__': None} {'name': 'Bruce', 'age': 25, 'weight': 180, 'tall': 185} person.tallis Bruce.tall: True
Bruce.tall += 3
print("person.tall is Bruce.tall: ", person.tall is Bruce.tall)
print(person.__dict__)
print(Bruce.__dict__)
del Bruce.tall
person.tall is Bruce.tall: False {'__module__': '__main__', 'tall': 180, 'hobbies': [], '__init__':, 'infoma': , '__dict__': , '__weakref__': , '__doc__': None} {'name': 'Bruce', 'age': 25, 'weight': 180, 'tall': 183}
print("person.hobbies is Bruce.hobbies: ", person.hobbies is Bruce.hobbies)
Bruce.hobbies = ["C#", "Python"]
print ("person.hobbies is Bruce.hobbies : ", person.hobbies is Bruce.hobbies)
print( person.__dict__)
print( Bruce.__dict__)
del Bruce.hobbies
print( "person.hobbies is Bruce.hobbies: ", person.hobbies is Bruce.hobbies)
person.hobbies is Bruce.hobbies: True person.hobbies is Bruce.hobbies : False {'__module__': '__main__', 'tall': 180, 'hobbies': [], '__init__':, 'infoma': , '__dict__': , '__weakref__': , '__doc__': None} {'name': 'Bruce', 'age': 25, 'weight': 180, 'hobbies': ['C#', 'Python']} person.hobbies is Bruce.hobbies: True
Bruce.hobbies.append("CSS") #内存地址没有新指向,在原来基础上扩展
print("person.hobbies is Bruce.hobbies: ", person.hobbies is Bruce.hobbies)
print(person.__dict__)
print(Bruce.__dict__)
person.hobbies is Bruce.hobbies: True {'__module__': '__main__', 'tall': 180, 'hobbies': ['CSS'], '__init__':, 'infoma': , '__dict__': , '__weakref__': , '__doc__': None} {'name': 'Bruce', 'age': 25, 'weight': 180}
对于不可变类型的类属性,隐藏属性可以总结为:
对于不可变类型的类属性person.tall,可以通过实例Bruce进行访问,并且”person.tall is Bruce.tall”
当通过实例赋值/修改tall属性的时候,将为实例Bruce新建一个tall实例属性,这时,”person.tall is not Bruce.tall”
对于可变类型的类属性,隐藏属性可以总结为:
ps:虽然通过实例可以访问类属性,但是,不建议这么做,最好还是通过类名来访问类属性,从而避免属性隐藏带来的不必要麻烦