python第七章再谈抽象

发布于:2025-02-10 ⋅ 阅读:(79) ⋅ 点赞:(0)

创建类

class person:
    def set_name(self,name):    #self为该类名称,将该类与name关联
        self.name=name
    def get_name(self):    #不设置也没问题
        return self.name
    def greet(self):
        print("hello,world!I'm{}".format(self.name))

        
foo=person()
foo.set_name('luke')
foo.greet()
hello,world!I'mluke
foo.name
'luke'

foo.greet()视为Person.greet(foo)的简写,但后者的多态性更低

原因:如果fooPerson的一个子类的实例,并且该子类重写了greet方法,但是你没有通过子类来调用该方法(即没有使用子类名.greet(foo)foo.greet(),其中foo是子类的实例),那么Python就不会调用子类中的重写方法,而是会调用Person类中的原始方法。因此,在这种情况下,多态性没有得到体现

让另一个变量指向同一个方法:

>>> class Bird: 
... 
 song = 'Squaawk!' 
... 
... 
 def sing(self): 
  print(self.song) 
... 
>>> bird = Bird() 
>>> bird.sing() 
Squaawk! 
>>> birdsong = bird.sing 
>>> birdsong() 
Squaawk! 

方法或属性成为私有的(不能从外部访问):只需让其名称以两个下划线打头即可

class Secretive:  
def __inaccessible(self): 
 print("Bet you can't see me ...") 
def accessible(self): 
 print("The secret message is:") 
 self.__inaccessible() 

绕过私有访问:

#正常访问
>>> s = Secretive() 
>>> s.__inaccessible() 
Traceback (most recent call last): 
 File "<stdin>", line 1, in <module> 
AttributeError: Secretive instance has no attribute '__inaccessible' 
>>> s.accessible() 
The secret message is: 
Bet you can't see me ... 

#绕过
>>> Secretive._Secretive__inaccessible 
<unbound method Secretive.__inaccessible>  
>>> s._Secretive__inaccessible() 
Bet you can't see me ... 

类内作用:

class MemberCounter:  
members = 0 
def init(self): 
 MemberCounter.members += 1 
>>> m1 = MemberCounter() 
>>> m1.init() 
>>> MemberCounter.members 
1 
>>> m2 = MemberCounter()     #m1.init()结果也为2
>>> m2.init() 
>>> MemberCounter.members 
2 

类中加类:共用语句,仅需修改不同之处(命名类需不同,但调用时方法相同)

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']

        
f=filter()
f.init()
f.filter([1,2,3])
[1, 2, 3]
a=spamfilter()
a.init()
a.filter(['apa','apsm','spam'])
['apa', 'apsm']
  • self 参数是对当前类实例的引用,它允许访问类的属性和其他方法。
  • sequence 参数是该方法接受的输入,它应该是一个可迭代对象(如列表、元组、字符串等),你想要从中过滤掉某些元素。

判断基类/子类/特定类的实例:

spamfilter.__bases__
                 
(<class '__main__.filter'>,)
#子类
>>> issubclass(SPAMFilter, Filter) 
True     #子类在前

>>> isinstance(s, SPAMFilter) 
True 

>>> s.__class__ 
<class __main__.SPAMFilter at 0x1707c0>

多重继承:

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 
>>> tc = TalkingCalculator() 
>>> tc.calculate('1 + 2 * 3') 
>>> tc.talk() 
Hi, my value is 7 

接口和内省:

#检查接口
hasattr(tc,'talk')
True
#检查加指定返回
callable(getattr(tc,'talk',None))
True
#设置类型
setattr(tc,'name','mr.gumby')
tc.name
'mr.gumby'

抽象基类:

from abc import ABC, abstractmethod  
class Talker(ABC): 
@abstractmethod 
def talk(self): 
 pass 

class Knigget(Talker):  
def talk(self): 
 print("Ni!") 

>>> k = Knigget() 
>>> isinstance(k, Talker) 
True 
>>> k.talk() 
Ni! 

关联超类:

class hearing:
    pass

h=hearing()
talker.register(hearing)
<class '__main__.hearing'>
isinstance(h,talker)
True
issubclass(hearing,talker)
True


网站公告

今日签到

点亮在社区的每一天
去签到