'''类:一类事物的抽象,用于定义抽象类型
实例:类的单个实际描述
如:人是一个类,而单个人是一个实例
用class来创建一个类,调用一个类来创建一个实例'''
class Person:
pass
xiaoming = Person()
xiaoming.name = 'xiaoming' # 创建实例属性,xiaoming的名字是xiaoming
xiaoming.age = 19 # 创建实例属性,xiaoming的年龄是19岁
p1 = Person()
p1.name = 'Bart'
p2 = Person()
p2.name = 'Lisa'
p3 = Person()
p3.name = 'Adam'
L1 = [p1, p2, p3]
L2 = sorted(L1, key=lambda x: x.name)
print(xiaoming.name, xiaoming.age)
print(L2[0].name, L2[1].name, L2[2].name)
class Person2(object):
def __init__(self, name, age): # __init__方法在调用类时会自动执行,而且参数中self是必须会有的,后面可以跟上自己想要的参数
self.name = name
self.age = age
p4 = Person2('xiaoming', 19)
print(p4.name, p4.age)
class Person3(object):
def __init__(self, name, gender, birth, **kw):
self.name = name
self.gender = gender
self.birth = birth
for k, v in kw.items(): # 在python3中移除了iteritems()方法
setattr(self, k, v)
xiaoming = Person3('Xiao Ming', 'Male', '1990-1-1', job='Student')
print(xiaoming.name)
print(xiaoming.job)
'''解释器内部会将 ** kw拆分成对应的dict.
setattr()
方法接受3个参数:setattr(对象,属性,属性的值)
此方法可以用来设置属性的值
setattr(self, k, v)
相当于self.k = v
kw.iteritems()
历遍字典kw的所有key和value,分别匹配k,v
'''
class Person5(object):
def __init__(self, name, score):
self.name = name
self.__score = score
p = Person5('Bob', 59)
# __xx表示该属性不能被外部访问且不能在子类中使用,__xx__表示可以被外部访问,_x表示可以在子类中使用
print(p.name)
try:
print(p.__score)
except AttributeError:
print('attributeError')
# 类也可以有自己的属性,如下所示:
class Person6(object):
count = 0
def __init__(self, name):
Person6.count = Person6.count + 1
self.name = name
p1 = Person6('Bob')
print(Person6.count)
# => 1
p2 = Person6('Alice')
print(Person6.count)
# => 2
p3 = Person6('Tim')
print(Person6.count)
# => 3
# 类属性是可以被类中的方法调用的,所有的类的实例也可以访问它所属的类的属性,但是当实例属性与类属性重名时,实例属性优先级高,它将屏蔽对类属性的访问。
class Person7(object):
__count = 0
def __init__(self, name):
self.__name = name
Person7.__count += 1
print(Person7.__count)
def get_name(self):
return self.__name
p1 = Person7('Bob')
p2 = Person7('Alice')
try:
print(Person7.__count)
except AttributeError:
print('AttributeError')
print(p1.get_name())
print(p1.get_name)
# 上面的代码说明类的实例真的可以访问它所属的类的属性...emmmmmm...好像重复了...
'''可见,千万不要在实例上修改类属性,它实际上并没有修改类属性,而是给实例绑定了一个实例属性.
还可以定义实例方法....emmmmm.感觉python中的类和java的类差不多呀...
实例方法也是属性,它实际上是一个函数对象,而types.MethodType()可以把一个函数变成一个方法
所以说上面的p1.get_name是函数对象,而p1.get_name()才是方法调用
简单来说,在类的外面的是函数,内部的方法。
用法区别:调用方法时,解释器会自动传入self参数,而调用普通函数则不会
函数不需要和实例对象 self 做绑定,而方法必须要和 self 绑定
'''
#在class中定义的是全部都是实例方法,实例方法的第一个函数参数是self,即实例本身,通过标记@classmethod可以将方法绑定到类上变成类方法,类方法的第一个参数通常是类本身,命名为cls
class Person8(object):
__count = 0
@classmethod
def how_many(cls):
return cls.__count
def __init__(self,name):
Person8.__count+=1
self.name=name
print (Person8.how_many())
p1 = (Person8('Bob'))
print (Person8.how_many())