-
对于Python的内建对象,比如int、dict、list等,通过str()方法,可以把这些对象转换为字符串对象输出。
对于自定义对象,通过str()方法,同样可以得到对象所对应的字符串结果。 例如<__main__.Person object at 0x7fc77b859c50>这个结果其实是自定义类的1个实例在内存中的地址。
通过str()打印的数据,是怎么来的呢?这其实是对象的内建方法__str__返回的。
如果我们的类也想把容易理解的字符串输出的话,那么我们也需要实现类的__str__()方法。
Python 定义了__str()__和__repr__()两种方法,__str()__用于显示给用户,而__repr__()用于显示给开发人员,当使用str()时,实际调用的是__str__()方法,而直接输入变量,调用的是__repr__()方法。
任务
请给Student 类定义__str__和__repr__方法,使得能打印出'Student: name, gender, score'。
# coding=utf-8 class Person(object): def __init__(self, name, gender): self.name = name self.gender = gender class Student(Person): def __init__(self, name, gender, score): super(Student, self).__init__(name, gender) self.score = score def __str__(self): return 'Student(name:{}, gender:{}, score:{})'.format(self.name, self.gender, self.score) def __repr__(self): return 'Student(name:{}, gender:{}, score:{})'.format(self.name, self.gender, self.score) s1 = Student('立里', '男', 100) s2 = Student('信兴', '男', 99) print(s1) print(s2)
查看全部 -
通过isinstance()方法,可以判断一个对象是否是某个类型,从某种意义上来讲,通过isinstance()方法,我们获取到了一个对象的一些信息,那有没有别的方法可以获取到对象更多的信息呢?
答:(1)通过type()函数,可以获得变量的类型。(2)通过dir()方法,可以获取变量的所有属性。
dir列出的属性中,有很多是以下划线开头和结尾的,这些都是特殊的方法,称为内建方法,在后面,我们还会学习这些方法。
对于自定义对象的实例变量,dir()返回所有实例属性,包括__class__这类有特殊意义的属性。注意到方法who也是p的一个属性。
dir()返回的属性是字符串列表,如果已知一个属性名称,要获取或者设置对象的属性,就需要用 getattr() 和 setattr( )函数了。
getattr(p, 'name') # 获取name属性 setattr(p, 'name', 'Adam') # 设置新的name属性 # 但是属性不存在,报错:AttributeError: 'Person' object has no attribute 'age' getattr(s, 'age', 20) # 获取age属性,如果属性不存在,就返回默认值20
#任务: # coding=utf-8 # 希望除了name和gender外,可以提供任意额外的关键字参数,并绑定到实例,请修改 Person 的__init__()定义,完成该功能。 # **kwargs 可变关键字参数,字典形式(k-v) class Person(object): def __init__(self, name, gender, **kwargs): self.name = name self.gender = gender for k, v in kwargs.items(): setattr(self, k, v) # 实例1: p1 = Person('莲华', '男', age = 24, work = '巫师') tamplate1 = '我叫{n},性别{g},{a}岁,任职{w}' str1 = tamplate1.format(n = p1.name, g = p1.gender, a = p1.age, w = p1.work) print(str1) # 实例2: p2 = Person('裘葵', '女', blood = 30000, work = '战士') tamplate2 = '我叫{n},性别{g},任职{w},血量{b}' str2 = tamplate2.format(n = p2.name, g = p2.gender, b = p2.blood, w = p2.work) print(str2)
查看全部 -
从定义上来讲,Student和Teacher都拥有来自父类Person继承的who()方法,以及自己定义的who()方法。但是在实际调用的时候,会首先查找自身的定义,如果自身有定义,则优先使用自己定义的函数;如果没有定义,则顺着继承链向上找。
在Boss的定义类,没有定义who方法,所以会顺着继承链向上找到父类的who方法并且调用。
除了从一个父类继承外,Python允许从多个父类继承,称为多重继承。多重继承和单继承没有特别大的差异,只是在括号内加入多个需要继承的类的名字即可。
在多重继承里,A虽然被继承了两次,但是__init__()的方法只调用一次。
多重继承的目的是从两种继承树中分别选择并继承出子类,以便组合功能使用。
Python的网络服务器有TCPServer、UDPServer、UnixStreamServer、UnixDatagramServer,而服务器运行模式有 多进程ForkingMixin 和 多线程ThreadingMixin两种。
要创建多进程模式的 TCPServer:
class MyTCPServer(TCPServer, ForkingMixin) pass
要创建多线程模式的 UDPServer:
class MyUDPServer(UDPServer, ThreadingMixin): pass
如果没有多重继承,要实现上述所有可能的组合需要 4x2=8 个子类。
查看全部 -
为了操作实例对象的私有属性,我们定义了实例方法;同样的,如果需要需要操作类的私有属性,则应该定义类的方法。
默认的,在class中定义的全部是实例方法,实例方法第一个参数 self 是实例本身。和实例方法不同的是,这里有两点需要特别注意:
1. 类方法需要使用@classmethod来标记为类方法,否则定义的还是实例方法。
2. 类方法的第一个参数将传入类本身,通常将参数名命名为 cls,上面的 cls.__localtion 实际上相当于Animal.__localtion。
因为是在类上调用,而非实例上调用,因此类方法无法获得任何实例变量,只能获得类的引用。
查看全部 -
通过函数isinstance()可以判断一个变量的类型。
在继承链上,一个父类的实例不能是子类类型,因为子类比父类多了一些属性和方法。
在一条继承链上,一个实例可以看成它本身的类型,也可以看成它父类的类型。isinstance也可以用于Python自有数据类型的判断。
任务
请根据继承链的类型转换,依次思考 t 是否是 Person,Student,Teacher,object 类型,并使用isinstance()判断来验证您的答案。
isinstance(t, Person) # True
isinstance(t, Student) #False
isinstance(t, Teacher) # True
isinstance(t, object) #True查看全部 -
定义Student类的时候,由于继承了Person类,所以Student类自动拥有name、gender属性,因此,在定义Student类的时候,只需要把额外的属性加上即可。
class Student(Person):
def __init__(self, name, gender, score):
super(Student, self).__init__(name, gender)
self.score = score
student = Student('Alice', 'girl', 100)
print(student.name) # ==> Alice
print(student.gender) # ==> girl
print(student.score) # ==> 100
注意:1. class Student()定义的时候,需要在括号内写明继承的类Person。
2. 在__init__()方法,需要调用super(Student, self).__init__(name, gender),来初始化从父类继承过来的属性。
任务
请参考Student类,编写Teacher类,老师拥有任教某个科目的属性。
class Teacher(Person):
def __init__(self, name, gender, course)
super(Teacher, self).__init__(name, gender)
self.course = course
teacher = Teacher('Eliot', 'boy', 'Chinese')
print(teacher.name)
print(teacher.gender)
print(teacher.course)查看全部 -
再通过把原先未私有化对象私有时,对象因为改变了私有属性而不被外部访问!!
查看全部 -
再通过在对象前加__ 从而使得对象变成私有,这样既不能改变对象的量,即不能从外部修改对象
查看全部 -
1.实例化对象跟类对象只有名字是相同,其他修改不相关
2.修改实例化不影响类对象,同理修改类对象不影响实例化对象
3.在实例化对象和类对象不要使用相同的名字!!!
查看全部 -
私有属性没有办法从外部访问,只能在类的内部操作;那如果外部需要操作私有属性怎么办?这个时候可以通过定义类或者实例的方法来操作私有属性。
实例的方法指的就是在类中定义的函数,实例方法的第一个参数永远都是self,self是一个引用,指向调用该方法的实例对象本身,除此以外,其他参数和普通函数是完全一样的。
__init__(self, name)其实也可看做是一个特殊的实例方法。
在外部调用实例方法时,是不需要显式传递self参数的。
name是实例的私有属性,从外部是无法访问的,而get_name(self) 就是一个实例方法,在实例方法里面是可以操作私有属性的,注意,它的第一个参数是self。__init__(self, name)其实也可看做是一个特殊的实例方法。任务
把Animal类的age、name、localtion定义成私有属性,并定义对应的方法修改和获取他们的值。class Animal(object): def __init__(self, name, age, localtion): self.__name = name self.__age = age self.__localtion = localtion def get_info(self): return 'name = {}, age = {}, localtion = {}'.format(self.__name, self.__age, self.__localtion) dog = Animal('wangwang', 1, 'GuangDong') print(dog.get_info())
查看全部 -
并不是所有的属性都可以被外部访问的,这种不能被外部访问的属性称为私有属性。私有属性是以双下划线'__'开头的属性。
# 类私有属性 class Animal(object): __localtion = 'Asia'
# 实例私有属性 class Animal(object): def __init__(self, name, age, localtion): self.name = name self.age = age self.__localtion = localtion
外部访问私有属性将会抛出异常,提示没有这个属性。
虽然私有属性无法从外部访问,但是,从类的内部是可以访问的。私有属性是为了保护类或实例属性不被外部污染而设计的。任务:
# 请给Animal类的__init__方法中添加name和age参数,并把age绑定到__age属性上,看看外部是否能访问到。
# Enter a code class Animal: def __init__(self, name, age, location): self.name = name self.__age = age self.__location = location cat = Animal('neko', 3, 'Home') dog = Animal('YY', 3, 'Zoom') print(dog.age) # 报错:AttributeError: Animal instance has no attribute 'age'
查看全部 -
属性可以分为类属性和实例属性。
在类属性和实例属性同时存在的情况下,实例属性的优先级是要高于类属性的,在操作实例的时候,优先是操作实例的属性。
当实例没有和类同名的时候,通过实例对象,依然可以访问到类属性。
通过实例是无法修改类的属性的,事实上,通过实例方法修改类属性,只是给实例绑定了一个对应的实例属性。
需要特别注意,尽量不要通过实例来修改类属性,否则很容易引发意想不到的错误。
任务:
# 请把上节的 Animal类属性 count 改为 __count,再试试能否从实例和类访问该属性。
# coding=utf-8 class Animal: __count = 0 def __init__(self, name, age): Animal.__count += 1 self.name = name self.age = age cat = Animal('neko', 3) dog = Animal('kk', 2) print(Animal.__count) print(cat.__count) print(dog.__count) # 以上三中方式都无法访问__count(前置双下划线),会报错:AttributeError: class Animal has no attribute '__count'
查看全部 -
class Animal(object): localtion = 'asia' def __init__(self, name, age): self.name = name self.age = age
类是抽象,是模板,而实例则是根据类创建的对象,比如类:动物,只是一个抽象,并没有动物的详细信息,而猫、狗等,则是具体的动物,是类的对象。
实例对象绑定的属性只属于这个实例,绑定在一个实例上的属性不会影响其它实例。
类也可以绑定属性,但是类的属性不属于任何一个对象,而是属于这个类。
如果在类上绑定一个属性,则所有实例都可以访问类的属性,并且,所有实例访问的类属性都是同一个。也就是说,实例属性每个实例各自拥有,互相独立,而类属性有且只有一份。
localtion就是属于Animal这个类的类属性,此后,通过Animal()实例化的所有对象,都可以访问到localtion,并且得到唯一的结果。
类属性也是可以动态添加和修改的,需要注意的是,因为类属性只有一份,所以改变了,所有实例可以访问到的类属性都会变更。
任务
请给 Animal类添加一个类属性 count,每创建一个实例,count 属性就加 1,这样就可以统计出一共创建了多少个 Animal的实例。
# coding=utf-8 class Animal: count = 0 def __init__(self, name, age): Animal.count += 1 self.name = name self.age = age cat = Animal('neko', 3) dog = Animal('saki', 2) print(dog.count) print(cat.count)
查看全部 -
类是抽象,是模板,而实例则是根据类创建的对象,比如类:动物,只是一个抽象,并没有动物的详细信息,而猫、狗等,则是具体的动物,是类的对象。
实例对象绑定的属性只属于这个实例,绑定在一个实例上的属性不会影响其它实例。
类也可以绑定属性,但是类的属性不属于任何一个对象,而是属于这个类。
如果在类上绑定一个属性,则所有实例都可以访问类的属性,并且,所有实例访问的类属性都是同一个。也就是说,实例属性每个实例各自拥有,互相独立,而类属性有且只有一份。
定义类属性可以直接在 class 中定义:
class Animal(object): localtion = 'asia' def __init__(self, name, age): self.name = name self.age = age
# coding=utf-8 class Animal: count = 0 def __init__(self, name, age): Animal.count += 1 self.name = name self.age = age cat = Animal('neko', 3) dog = Animal('saki', 2) print(dog.count) print(cat.count)
查看全部 -
类是抽象,是模板,而实例则是根据类创建的对象,比如类:动物,只是一个抽象,并没有动物的详细信息,而猫、狗等,则是具体的动物,是类的对象。
实例对象绑定的属性只属于这个实例,绑定在一个实例上的属性不会影响其它实例。
类也可以绑定属性,但是类的属性不属于任何一个对象,而是属于这个类。
如果在类上绑定一个属性,则所有实例都可以访问类的属性,并且,所有实例访问的类属性都是同一个。也就是说,实例属性每个实例各自拥有,互相独立,而类属性有且只有一份。
定义类属性可以直接在 class 中定义:
class Animal(object): localtion = 'asia' def __init__(self, name, age): self.name = name self.age = age
localtion就是属于Animal这个类的类属性,此后,通过Animal()实例化的所有对象,都可以访问到localtion,并且得到唯一的结果。
类属性也是可以动态添加和修改的,需要注意的是,因为类属性只有一份,所以改变了,所有实例可以访问到的类属性都会变更。
任务
请给 Animal类添加一个类属性 count,每创建一个实例,count 属性就加 1,这样就可以统计出一共创建了多少个 Animal的实例。
查看全部 -
类是抽象,是模板,而实例则是根据类创建的对象,比如类:动物,只是一个抽象,并没有动物的详细信息,而猫、狗等,则是具体的动物,是类的对象。
实例对象绑定的属性只属于这个实例,绑定在一个实例上的属性不会影响其它实例。
类也可以绑定属性,但是类的属性不属于任何一个对象,而是属于这个类。
如果在类上绑定一个属性,则所有实例都可以访问类的属性,并且,所有实例访问的类属性都是同一个。也就是说,实例属性每个实例各自拥有,互相独立,而类属性有且只有一份。
定义类属性可以直接在 class 中定义:
class Animal(object): localtion = 'asia' def __init__(self, name, age): self.name = name self.age = age
localtion就是属于Animal这个类的类属性,此后,通过Animal()实例化的所有对象,都可以访问到localtion,并且得到唯一的结果。
类属性也是可以动态添加和修改的,需要注意的是,因为类属性只有一份,所以改变了,所有实例可以访问到的类属性都会变更。
任务
请给 Animal类添加一个类属性 count,每创建一个实例,count 属性就加 1,这样就可以统计出一共创建了多少个 Animal的实例。
# coding=utf-8 class Animal: count = 0 def __init__(self, name, age): Animal.count += 1 self.name = name self.age = age cat = Animal('neko', 3) dog = Animal('saki', 2) print(dog.count) print(cat.count)
查看全部 -
类是抽象,是模板,而实例则是根据类创建的对象,比如类:动物,只是一个抽象,并没有动物的详细信息,而猫、狗等,则是具体的动物,是类的对象。
实例对象绑定的属性只属于这个实例,绑定在一个实例上的属性不会影响其它实例。
类也可以绑定属性,但是类的属性不属于任何一个对象,而是属于这个类。
如果在类上绑定一个属性,则所有实例都可以访问类的属性,并且,所有实例访问的类属性都是同一个。也就是说,实例属性每个实例各自拥有,互相独立,而类属性有且只有一份。
定义类属性可以直接在 class 中定义:
class Animal(object): localtion = 'Asia' def __init__(self, name, age): self.name = name self.age = age
localtion就是属于Animal这个类的类属性,此后,通过Animal()实例化的所有对象,都可以访问到localtion,并且得到唯一的结果。
类属性也是可以动态添加和修改的,需要注意的是,因为类属性只有一份,所以改变了,所有实例可以访问到的类属性都会变更。
任务
请给 Animal类添加一个类属性 count,每创建一个实例,count 属性就加 1,这样就可以统计出一共创建了多少个 Animal的实例。
# coding=utf-8 class Animal: count = 0 def __init__(self, name, age): Animal.count += 1 self.name = name self.age = age cat = Animal('neko', 3) dog = Animal('saki', 2) print(dog.count) print(cat.count)
查看全部 -
类是抽象,是模板,而实例则是根据类创建的对象,比如类:动物,只是一个抽象,并没有动物的详细信息,而猫、狗等,则是具体的动物,是类的对象。
实例对象绑定的属性只属于这个实例,绑定在一个实例上的属性不会影响其它实例。
类也可以绑定属性,但是类的属性不属于任何一个对象,而是属于这个类。
如果在类上绑定一个属性,则所有实例都可以访问类的属性,并且,所有实例访问的类属性都是同一个。也就是说,实例属性每个实例各自拥有,互相独立,而类属性有且只有一份。
定义类属性可以直接在 class 中定义:
class Animal(object): localtion = 'Asia' def __init__(self, name, age): self.name = name self.age = age
localtion就是属于Animal这个类的类属性,此后,通过Animal()实例化的所有对象,都可以访问到localtion,并且得到唯一的结果。
类属性也是可以动态添加和修改的,需要注意的是,因为类属性只有一份,所以改变了,所有实例可以访问到的类属性都会变更。
任务
请给 Animal类添加一个类属性 count,每创建一个实例,count 属性就加 1,这样就可以统计出一共创建了多少个 Animal的实例。
# coding=utf-8 class Animal: count = 0 def __init__(self, name, age): Animal.count += 1 self.name = name self.age = age cat = Animal('Neko', 3) dog = Animal('Saki', 2) print(dog.count) print(cat.count)
查看全部 -
类是抽象,是模板,而实例则是根据类创建的对象,比如类:动物,只是一个抽象,并没有动物的详细信息,而猫、狗等,则是具体的动物,是类的对象。
实例对象绑定的属性只属于这个实例,绑定在一个实例上的属性不会影响其它实例。
类也可以绑定属性,但是类的属性不属于任何一个对象,而是属于这个类。
如果在类上绑定一个属性,则所有实例都可以访问类的属性,并且,所有实例访问的类属性都是同一个。也就是说,实例属性每个实例各自拥有,互相独立,而类属性有且只有一份。
定义类属性可以直接在 class 中定义:
class Animal(object): localtion = 'Asia' def __init__(self, name, age): self.name = name self.age = age
localtion就是属于Animal这个类的类属性,此后,通过Animal()实例化的所有对象,都可以访问到localtion,并且得到唯一的结果。
类属性也是可以动态添加和修改的,需要注意的是,因为类属性只有一份,所以改变了,所有实例可以访问到的类属性都会变更。
任务
请给 Animal类添加一个类属性 count,每创建一个实例,count 属性就加 1,这样就可以统计出一共创建了多少个 Animal的实例。
# coding=utf-8 class Animal: count = 0 def __init__(self, name, age): Animal.count += 1 self.name = name self.age = age cat = Animal('Neko', 3) dog = Animal('Saki', 2) print(dog.count) print(cat.count)
查看全部 -
类是抽象,是模板,而实例则是根据类创建的对象,比如类:动物,只是一个抽象,并没有动物的详细信息,而猫、狗等,则是具体的动物,是类的对象。
实例对象绑定的属性只属于这个实例,绑定在一个实例上的属性不会影响其它实例。
类也可以绑定属性,但是类的属性不属于任何一个对象,而是属于这个类。
如果在类上绑定一个属性,则所有实例都可以访问类的属性,并且,所有实例访问的类属性都是同一个。也就是说,实例属性每个实例各自拥有,互相独立,而类属性有且只有一份。
定义类属性可以直接在 class 中定义:
class Animal(object): localtion = 'Asia' def __init__(self, name, age): self.name = name self.age = age
localtion就是属于Animal这个类的类属性,此后,通过Animal()实例化的所有对象,都可以访问到localtion,并且得到唯一的结果。
类属性也是可以动态添加和修改的,需要注意的是,因为类属性只有一份,所以改变了,所有实例可以访问到的类属性都会变更。
任务
请给 Animal类添加一个类属性 count,每创建一个实例,count 属性就加 1,这样就可以统计出一共创建了多少个 Animal的实例。
# coding=utf-8 class Animal: count = 0 def __init__(self, name, age): Animal.count += 1 self.name = name self.age = age cat = Animal('Neko', 3) dog = Animal('Saki', 2) print(dog.count) print(cat.count)
查看全部 -
在定义 Person 类时,可以为Person类添加一个特殊的__init__()方法,当创建实例时,__init__()方法被自动调用,我们就能在此为每个实例都统一加上以下属性:
class Person(object): def __init__(self, name, sex, age): self.name = name self.sex = sex self.age = age
__init__() 方法的第一个参数必须是 self(也可以用别的名字,但建议使用习惯用法),后续参数则可以自由指定,和定义函数没有任何区别。
定义类后,就可以相应的实例化对象了,需要注意的是,在实例化的时候,需要提供除self以外的所有参数。xiaoming = Person('Xiao Ming', 'boy', 13) xiaohong = Person('Xiao Hong', 'girl', 14)
任务:
# 请定义一个动物类,抽象出名字、年龄两个属性,并实例化两个实例dog, cat。
# coding=utf-8 class Animal: def __init__(self, name, age): self.name = name self.age = age cat = Animal("neko", 2) dog = Animal("yinu", 3) template = '{n1}的名字叫:{n2},年龄是:{a}岁。' d = 'dog' c = 'cat' dn = dog.name cn = cat.name da = dog.age ca = cat.age str1 = template.format(n1 = d, n2 = dn, a = da) str2 = template.format(n1 = c, n2 = cn, a = ca) print(str1) print(str2)
查看全部 -
通过以下的方式赋予实例这些属性,并且把这些属性打印出来。
xiaohong.name = 'xiaohong' xiaohong.sex = 'girl' xiaohong.age = 13 print(xiaohong.name) print(xiaohong.sex) print(xiaohong.age)
这些属性也可以和普通变量一样进行运算。
xiaohong.age = xiaohong.age + 1
任务:
# 请定义一个动物类,并创建出两个实例dog, cat,分别赋予不同的名字和年龄并打印出来。
# coding=utf-8 class Animal: pass dog = Animal() cat = Animal() dog.name = '旺财' cat.name = 'Neko' dog.age = 2 cat.age = 3 tamplate = '{n1} 的名字是:{n2},年龄是:{a}岁' d = 'dog' c = 'cat' dn = dog.name cn = cat.name da = dog.age ca = cat.age str1 = tamplate.format(n1 = d, n2 = dn, a = da) str2 = tamplate.format(n1 = c, n2 = cn, a = ca) print(str1) print(str2) # 结果如下: # dog 的名字是:旺财,年龄是:2岁 # cat 的名字是:Neko,年龄是:3岁
查看全部 -
Python中通过class关键字定义一个类。类名以大写字母开头。
class Person: pass
class Person(): pass
class Person(object): pass
在Python3中,我们只需要知道这三种方式都可以定义一个类即可。
实例化是指,把抽象的类,赋予实物的过程。
创建实例使用类名+(),类似函数调用的形式创建:
class Person(object): pass xiaohong = Person() xiaoming = Person()
任务:
# 请练习定义一个动物类,并创建出两个实例dog, cat,打印实例,再比较两个实例是否相等。
# Enter a code class Animal: pass dog = Animal() cat = Animal() print(cat) print(dog) print(cat == dog) print(cat is dog) # 结果如下 : # <__main__.Animal instance at 0x7f38e43873f8> # <__main__.Animal instance at 0x7f38e4383050> # False # False
查看全部
举报