python中继承一个类 |
class Person(object): def __init__(self, name, gender): self.name = name self.gender = gender 定义Student类时,只需要把额外的属性加上,例如score: class Student(Person): def __init__(self, name, gender, score): super(Student, self).__init__(name, gender) self.score = score |
python中判断类型函数isinstance()可以判断一个变量的类型,既可以用在Python内置的数据类型如str、list、dict,也可以用在我们自定义的类,它们本质上都是数据类型。 |
print isinstance(t,Person) 一个父类的实例不能是子类类型,因为子类比父类多了一些属性和方法。 一个实例可以看成它本身的类型,也可以看成它父类的类型。 |
python中多态s 是Student类型,它实际上拥有自己的 whoAmI()方法以及从 Person继承的 whoAmI方法,但调用 s.whoAmI()总是先查找它自身的定义,如果没有定义,则顺着继承链向上查找,直到在某个父类中找到为止。 |
Python提供了open()函数来打开一个磁盘文件,并返回 File 对象。File对象有一个read()方法可以读取文件内容: 例如,从文件读取内容并解析为JSON结果: import json f = open('/path/to/file.json', 'r') print json.load(f) 由于Python的动态特性,json.load()并不一定要从一个File对象读取内容。任何对象,只要有read()方法,就称为File-like Object,都可以传给json.load()。 请尝试编写一个File-like Object,把一个字符串 r'["Tim", "Bob", "Alice"]'包装成 File-like Object 并由 json.load() 解析: import json
class Students(object):
def read(self): return r'["Tim", "Bob", "Alice"]' s = Students()
print json.load(s)
|
python中多重继承除了从一个父类继承外,Python允许从多个父类继承,称为多重继承 |
class Person(object):
pass class Student(Person):
pass class Teacher(Person):
pass class SkillMixin(object):
pass class BasketballMixin(SkillMixin):
def skill(self): return 'basketball' class FootballMixin(SkillMixin):
def skill(self): return 'football' class BStudent(Student,BasketballMixin):
pass class FTeacher(Teacher,FootballMixin):
pass s = BStudent()
print s.skill() t = FTeacher()
print t.skill() |
python中获取对象信息拿到一个变量,除了用 isinstance() 判断它是否是某种类型的实例外,还有没有别的方法获取到更多的信息呢? |
可以用 dir() 函数获取变量的所有属性: class Person(object): Person.age=25 print ("dir:",dir(p))
>>> dir(s) ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', 如何去掉`__xxx__`这类的特殊属性,只保留我们自己定义的属性?回顾一下filter()函数的用法
class Person(object):
def __init__(self, name, gender, **kw):
self.name=name self.gender=gender for k,v in kw.items(): setattr(self, k, v) p = Person('Bob', 'Male', age=18, course='Python')
print getattr(p, 'age')
print p.course |
python中什么是特殊方法 特殊方法是定义在class中的 不需要直接去调这些特殊的方法 python的某些函数或者操作符回去自动调用相应的特殊方法 |
|
python中 __str__和__repr__如果要把一个类的实例变成 str,就需要实现特殊方法__str__() |
class Person(object): def __init__(self, name, gender): self.name = name self.gender = gender def __str__(self): return '(Person: %s, %s)' % (self.name, self.gender) >>> p = Person('Bob', 'male')
>>> print p
(Person: Bob, male)
|
python中 __cmp__对 int、str 等内置数据类型排序时,Python的 sorted() 按照默认的比较函数 cmp 排序,但是,如果对一组 Student 类的实例排序时,就必须提供我们自己的特殊方法 __cmp__(): |
class Student(object):
def __init__(self, name, score):
self.name = name self.score = score def __str__(self):
return '(%s: %s)' % (self.name, self.score) __repr__ = __str__
def __cmp__(self, s):
if self.score <s.score: return 1 elif self.score > s.score: return -1 else: if self.name < s.name: return -1 elif self.name > s.name: return 1 return 0 class Student(object):
def __init__(self, name, score):
self.name = name
self.score = score
def __str__(self):
return '(%s: %s)' % (self.name, self.score)
__repr__ = __str__
def __cmp__(self, s):
if self.score == s.score:
return cmp(self.name, s.name)
return -cmp(self.score, s.score)
|
python中 __len__如果一个类表现得像一个list,要获取有多少个元素,就得用 len() 函数。 要让 len() 函数工作正常,类必须提供一个特殊方法__len__(),它返回元素的个数。 |
例如,我们写一个 Students 类,把名字传进去: class Students(object):
def __init__(self, *args):
self.names = args
def __len__(self):
return len(self.names)
只要正确实现了__len__()方法,就可以用len()函数返回Students实例的“长度”: >>> ss = Students('Bob', 'Alice', 'Tim') >>> print len(ss) 3 class Fib(object):
def __init__(self, num):
self.num = num self.L = [0,1] for n in range(num-2): next_num = self.L[n]+self.L[n+1] self.L.append(next_num) def __str__(self): return str(self.L) def __len__(self): return self.num >>>f = Fib(10)
>>>print f 方法二:
def __init__(self, num):
a, b, L = 0, 1, []
for n in range(num):
L.append(a)
a, b = b, a + b
self.numbers = L
|
python中 @property |
给属性赋值怎么检查分数的有效性: class Student(object):
def __init__(self, name, score):
self.name = name
self.__score = score
def get_score(self):
return self.__score
def set_score(self, score):
if score < 0 or score > 100:
raise ValueError('invalid score')
self.__score = score
这种使用 get/set 方法来封装对一个属性的访问在许多面向对象编程的语言中都很常见。 但是写 s.get_score() 和 s.set_score() 没有直接写 s.score 来得直接。 有没有两全其美的方法?----有。 因为Python支持高阶函数,在函数式编程中我们介绍了装饰器函数,可以用装饰器函数把 get/set 方法“装饰”成属性调用: class Student(object): def __init__(self, name, score): self.name = name self.__score = score @property def score(self): return self.__score @score.setter def score(self, score): if score < 0 or score > 100: raise ValueError('invalid score') self.__score = score >>> s = Student('Bob', 59) >>> s.score = 60 >>> print s.score 60 >>> s.score = 1000 Traceback (most recent call last): ... ValueError: invalid score |
python中 __slots__由于Python是动态语言,任何实例在运行期都可以动态地添加属性。 如果要限制添加的属性,例如,Student类只允许添加 name、gender和score 这3个属性,就可以利用Python的一个特殊的__slots__来实现。 顾名思义,__slots__是指一个类允许的属性列表: __slots__的目的是限制当前类所能拥有的属性,如果不需要添加任意动态的属性,使用__slots__也能节省内存。 |
class Student(object): __slots__ = ('name', 'gender', 'score') def __init__(self, name, gender, score): self.name = name self.gender = gender self.score = score >>> s = Student('Bob', 'male', 59) >>> s.name = 'Tim' # OK >>> s.score = 99 # OK >>> s.grade = 'A' Traceback (most recent call last): ... AttributeError: 'Student' object has no attribute 'grade' class Person(object):
__slots__ = ('name', 'gender')
def __init__(self, name, gender):
self.name = name self.gender = gender class Student(Person):
__slots__ = ('score')
def __init__(self,score,name,gender):
super(Student,self).__init__(name, gender) self.score=score s = Student('Bob', 'male', 59)
s.name = 'Tim' s.score = 99 print s.score |
python中 __call__在Python中,函数其实是一个对象: >>> f = abs >>> f.__name__ 'abs' >>> f(-123) 123 由于 f 可以被调用,所以,f 被称为可调用对象。 所有的函数都是可调用对象。 一个类实例也可以变成一个可调用对象,只需要实现一个特殊方法__call__() |
我们把 Person 类变成一个可调用对象: class Person(object): def __init__(self, name, gender): self.name = name self.gender = gender def __call__(self, friend): print 'My name is %s...' % self.name print 'My friend is %s...' % friend 现在可以对 Person 实例直接调用: >>> p = Person('Bob', 'male') >>> p('Tim') My name is Bob... My friend is Tim... 单看 p('Tim') 你无法确定 p 是一个函数还是一个类实例,所以,在Python中,函数也是对象,对象和函数的区别并不显著。 class Fib(object):
def __call__(self,num): a,b,L=0,1,[] for n in range(num): L.append(a) a,b=b,a+b return L f = Fib()
print f(10) |