《Beginning Python From Novice to Professional》学习笔记九:More Abstraction

0.类的私有性
Python中对象的属性是可以从外部访问的,本身不直接支持私有性,对此的解释是
Isn’t it enough that each object manages its own attributes?
在Python中如果要使方法或属性从外部不可访问,则必须在名字前加上两个下划线 
class Secretive: def __inaccessible(self): print "Bet you can't see me..." def accessible(self): print "The secret message is:" self.__inaccessible()  
  
方法__inaccessible则外部不可见,但实际在类的定义时,双下划线开始的方法会被自动“转换”为名字前加上单下划线再加上类名
Secretive._Secretive__inaccessible
---> <unbound method Secretive.__inaccessible>
s._Secretive__inaccessible()
---> Bet you can't see me...

1.创建类
class Person: def setName(self, name): self.name = name def getName(self): return self.name def greet(self): print "Hello, world! I'm %s." % self.name foo = Person() #注意这里的括号 foo.setName('hello') foo.greet() #---> Hello, world! I'm hello.
习惯上第一个参数都是self,传递参数时不用写出。self是用来甄别不同的实例对象的
注意此时name属性对外是可见的。

此外实例中的函数可动态更改(注意不是类的函数)
def fun():
    print "haha, You'll be terminated!"
    
foo.greet = fun
foo.greet()   ---> haha, You'll be terminated!

以上的方法均为bound method,是与某个实例绑定的。

下面是个综合例子,结合函数一章中的几个技巧
class FoodExpert: def init(self): self.goodFood = [] def addGoodFood(self, food): self.goodFood.append(food) def likes(self, x): return x in self.goodFood def prefers(self, x, y): x_rating = self.goodFood.index(x) y_rating = self.goodFood.index(y) if x_rating > y_rating: return y else: return x f = FoodExpert() f.init() map(f.addGoodFood, ['SPAM', 'Eggs', 'Bacon', 'Rat', 'Spring Surprise']) #---> [None, None, None, None, None] #返回None是因为addGoodFood
函数没有返回值
f.goodFood
---> ['SPAM', 'Eggs', 'Bacon', 'Rat', 'Spring Surprise']
menu = ['Filet Mignon', 'Pasta', 'Pizza', 'Eggs', 'Bacon', 'Tomato', 'SPAM']
rec = filter(f.likes, menu)
rec   ---> ['Eggs', 'Bacon', 'SPAM']
reduce(f.prefers, rec)   ---> 'SPAM'


2.类的名字空间
class MemberCounter: members = 0 #相当于C++类的静态变量,可以被所有实例对象访问 def init(self): MemberCounter.members += 1 self.mymember = 0 #有self空间,因此只能被创建它的实例访问 def add(self): self.mymember += 1

m1 = MemberCounter()
m1.init()
m1.add()
m2 = MemberCounter()
m2.init()
m2.add()
MemberCounter.members   ---> 2
m2.members  ---> 2
m2.mymember  ---> 1

但是一旦有实例对class中的变量赋值,该变量即被Rebind到该实例
m1.members = "hello"
m1.members   ---> "hello"
m2.members   ---> 2


3.指定SuperClassic(继承)
class Filter: def init(self): self.blocked = [] def filter(self, sequence): return [x for x in sequence if x not in self.blocked] class SPAMFilter(Filter): #继承 def init(self): #覆盖 self.blocked = ['SPAM']

4.判断父子关系
issubclass(SPAMFilter, Filter)   ---> True
issubclass(Filter, SPAMFilter)   ---> False

也可以直接得到父类
SPAMFilter.__bases__
---> (<class __main__.Filter at 0x171e40>,)
Filter.__bases__   ---> ()


5.判断是否为其实例
s = SPAMFilter()
isinstance(s, SPAMFilter)   ---> True
isinstance(s, Filter)   ---> True  
#注意这里也是True
isinstance(s, str)   ---> False
也可以直接得到类信息
s.__class__   --->
<class __main__.SPAMFilter at 0x1707c0>


6.多重SuperClass(多重继承)
class Calculator: def calculate(self, expression): self.value = eval(expression) class Talker: def talk(self): print 'Hi, my value is', self.value class TalkingCalculator(Calculator, Talker): pass #!多重继承要注意 The methods in the earlier classes override the methods in the later ones. 父类的顺序是有影响的。

7.对接口的检测
Python中不需要显式地写出接口,你可检测它
tc = TalkingCalculator()
hasattr(tc, 'talk')   ---> True
hasattr(tc, 'fnord')   ---> False
还可以检测是否可调用
callable(getattr(tc, 'talk', None))   ---> True
callable(getattr(tc, 'fnord', None))   ---> False

#其中getattr返回函数对象,且可以提供默认值,此处为None
#getattr的逆函数为setattr,它可以为对象增加一个属性
setattr(tc, 'name', 'Mr. Gumby')
tc.name   ---> 'Mr. Gumby'

#obj.__dict__可返回obj对象的所有属性。

你可能感兴趣的:(spring,python,filter,Class,menu,methods)