创建类
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)的简写,但后者的多态性更低
原因:如果
foo
是Person
的一个子类的实例,并且该子类重写了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