在Python中,类本身是一个对象,也是命名空间,支持多个对象的产生,命名空间的继承以及运算符重载。是产生多个实例的工厂。
class FirstClass:
def setdata(self, value):
self.data = value
def display(self):
print(self.data)
def main():
x = FirstClass()
y = FirstClass()
x.setdata(123)
y.setdata("abc")
x.display()
y.display()
if __name__ == '__main__':
main()
# 输出:
# 123
# abc
类继承是实现编写类层次结构的大门。
class FirstClass:
def setdata(self, value):
self.data = value
def display(self):
print(self.data)
class SecondClass(FirstClass):
# display函数的覆盖,不是修改了FirstClass,而是对其完成了定制。
def display(self):
print('Current value = %s' % self.data)
def main():
x = FirstClass()
y = SecondClass()
x.setdata(123)
y.setdata("abc")
x.display()
y.display()
if __name__ == '__main__':
main()
# 输出:
# 123
# Current value = abc
有关运算符重载的详细用法,也可参阅笔者博客Python进阶与拾遗4:Python中的运算符重载。
class FirstClass:
def setdata(self, value):
self.data = value
def display(self):
print(self.data)
class SecondClass(FirstClass):
def display(self):
print('Current value = %s' % self.data)
class ThirdClass(SecondClass):
def __init__(self,value):
self.data = value
def __add__(self, other):
return ThirdClass(self.data + other)
def __str__(self):
return '[ThirdClass: %s]' % self.data
def mul(self, other):
self.data *= other
def main():
x = FirstClass()
y = SecondClass()
z = ThirdClass(3.1415926)
x.setdata(123)
y.setdata("abc")
x.display()
y.display()
z.display()
z_1 = z + 10
print(x)
print(y)
print(z)
print(z_1)
if __name__ == '__main__':
main()
'''
输出:
123
Current value = abc
Current value = 3.1415926
<__main__.FirstClass object at 0x00000138DF5A94C0>
<__main__.SecondClass object at 0x00000138DF62E220>
[ThirdClass: 3.1415926]
[ThirdClass: 13.1415926]
'''
本小节将从用例的角度出发分享类的编写步骤。一般来说,类名使用大写字母开头,而模块名使用小写字母开头。
class Person:
def __init__(self, name, job=None, pay=0):
self.name = name
self.job = job
self.pay = pay
def main():
# 两个实例对象都是命令空间对象,每一个都拥有各自类所创建的状态信息的独立副本。
bob = Person('Bob Smith')
sue = Person('Sue Jones', job='Teacher', pay=100000)
print(bob.name, bob.pay)
print(sue.name, sue.pay)
if __name__ == "__main__":
main()
'''
输出:
Bob Smith 0
Sue Jones 100000
'''
方法定义了处理那些类的实例的常规函数,实例是方法调用的主体,并且会自动传递方法给self参数。Python通过自动把实例传递给第一个参数从而告诉一个方法应该处理哪个实例,通常这个参数叫self。在调用时,有两种语法,可以通过实例进行方法调用,也可以通过类进行方法调用。
# 方法调用
Instance.method(args)
Class.method(instance, args)
class Person:
def __init__(self, name, job=None, pay=0):
self.name = name
self.job = job
self.pay = pay
def lastName(self):
return self.name.split()[-1]
def giveRaise(self, percent):
self.pay = int(self.pay * (1 + percent))
def main():
bob = Person('Bob Smith')
sue = Person('Sue Jones', job='Teacher', pay=100000)
print(bob.name, bob.pay)
print(sue.name, sue.pay)
print(bob.lastName(), sue.lastName())
# print(Person.lastName(bob), Person.lastName(sue)) # 同理
sue.giveRaise(.10)
# Person.giveRaise(sue, .10) # 同理
print(sue.pay)
if __name__ == "__main__":
main()
'''
输出:
Bob Smith 0
Sue Jones 100000
Smith Jones
110000
'''
class Person:
def __init__(self, name, job=None, pay=0):
self.name = name
self.job = job
self.pay = pay
def lastName(self):
return self.name.split()[-1]
def giveRaise(self, percent):
self.pay = int(self.pay * (1 + percent))
def __str__(self):
return '[Person: %s, %s]' % (self.name, self.pay)
def main():
bob = Person('Bob Smith')
sue = Person('Sue Jones', job='Teacher', pay=100000)
print(bob)
print(sue)
print(bob.lastName(), sue.lastName())
sue.giveRaise(.10)
print(sue)
if __name__ == "__main__":
main()
'''
输出:
[Person: Bob Smith, 0]
[Person: Sue Jones, 100000]
Smith Jones
[Person: Sue Jones, 110000]
'''
class Person:
def __init__(self, name, job=None, pay=0):
self.name = name
self.job = job
self.pay = pay
def lastName(self):
return self.name.split()[-1]
def giveRaise(self, percent):
self.pay = int(self.pay * (1 + percent))
def __str__(self):
return '[Person: %s, %s]' % (self.name, self.pay)
class Manager(Person):
def giveRaise(self, percent, bonus=.10):
Person.giveRaise(self, percent + bonus)
def main():
bob = Person('Bob Smith')
sue = Person('Sue Jones', job='Teacher', pay=100000)
print(bob)
print(sue)
print(bob.lastName(), sue.lastName())
sue.giveRaise(.10)
print(sue)
tom = Manager('Tom Jones', 'mgr', 50000)
tom.giveRaise(.10)
print(tom.lastName())
print(tom)
if __name__ == "__main__":
main()
'''
输出:
[Person: Bob Smith, 0]
[Person: Sue Jones, 100000]
Smith Jones
[Person: Sue Jones, 110000]
Jones
[Person: Tom Jones, 60000]
'''
在多重继承类的对象搜索属性时,Python会由坐至右搜索类首行中的超类,直到找到相符者。
多态是,针对同样名称的成员方法,对不同的实例使用不同的定制版本。
class Person:
def __init__(self, name, job=None, pay=0):
self.name = name
self.job = job
self.pay = pay
def lastName(self):
return self.name.split()[-1]
def giveRaise(self, percent):
self.pay = int(self.pay * (1 + percent))
def __str__(self):
return '[Person: %s, %s]' % (self.name, self.pay)
class Manager(Person):
def giveRaise(self, percent, bonus=.10):
Person.giveRaise(self, percent + bonus)
def main():
bob = Person('Bob Smith')
sue = Person('Sue Jones', job='Teacher', pay=100000)
print(bob)
print(sue)
print(bob.lastName(), sue.lastName())
sue.giveRaise(.10)
print(sue)
tom = Manager('Tom Jones', 'mgr', 50000)
tom.giveRaise(.10)
print(tom.lastName())
print(tom)
print("==All three==")
for object in (bob, sue, tom):
object.giveRaise(.10)
print(object)
if __name__ == "__main__":
main()
'''
输出:
[Person: Bob Smith, 0]
[Person: Sue Jones, 100000]
Smith Jones
[Person: Sue Jones, 110000]
Jones
[Person: Tom Jones, 60000]
==All three==
[Person: Bob Smith, 0]
[Person: Sue Jones, 121000]
[Person: Tom Jones, 72000]
'''
class Person:
def __init__(self, name, job=None, pay=0):
self.name = name
self.job = job
self.pay = pay
def lastName(self):
return self.name.split()[-1]
def giveRaise(self, percent):
self.pay = int(self.pay * (1 + percent))
def __str__(self):
return '[Person: %s, %s]' % (self.name, self.pay)
class Manager(Person):
def __init__(self, name, pay):
Person.__init__(self, name, 'mgr', pay)
# super().__init__(name, 'mgr', pay) # 同理
def giveRaise(self, percent, bonus=.10):
Person.giveRaise(self, percent + bonus)
def main():
bob = Person('Bob Smith')
sue = Person('Sue Jones', job='Teacher', pay=100000)
print(bob)
print(sue)
print(bob.lastName(), sue.lastName())
sue.giveRaise(.10)
print(sue)
tom = Manager('Tom Jones', 50000)
tom.giveRaise(.10)
print(tom.lastName())
print(tom)
if __name__ == "__main__":
main()
'''
输出:
[Person: Bob Smith, 0]
[Person: Sue Jones, 100000]
Smith Jones
[Person: Sue Jones, 110000]
Jones
[Person: Tom Jones, 60000]
'''
内省工具是特殊的属性与函数,允许我们访问对象实现的一些内部机制。
典型的内省工具:
class Person:
def __init__(self, name, job=None, pay=0):
self.name = name
self.job = job
self.pay = pay
def lastName(self):
return self.name.split()[-1]
def giveRaise(self, percent):
self.pay = int(self.pay * (1 + percent))
def __str__(self):
return '[Person: %s, %s]' % (self.name, self.pay)
class Manager(Person):
def __init__(self, name, pay):
Person.__init__(self, name, 'mgr', pay)
def giveRaise(self, percent, bonus=.10):
Person.giveRaise(self, percent + bonus)
def main():
bob = Person('Bob Smith')
tom = Manager('Tom Jones', 50000)
tom.giveRaise(.10)
print(list(bob.__dict__))
print(dir(bob))
print("------------------------------")
print(tom.__dict__)
print(dir(tom))
print("------------------------------")
print(Person.__dict__)
print(Person.__name__)
print(Person.__bases__)
print(dir(Person))
print("------------------------------")
print(Manager.__dict__)
print(Manager.__name__)
print(Manager.__bases__)
print(dir(Manager))
if __name__ == "__main__":
main()
'''
输出:
['name', 'job', 'pay']
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'giveRaise', 'job', 'lastName', 'name', 'pay']
------------------------------
{'name': 'Tom Jones', 'job': 'mgr', 'pay': 60000}
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'giveRaise', 'job', 'lastName', 'name', 'pay']
------------------------------
{'__module__': '__main__', '__init__': , 'lastName': , 'giveRaise': , '__str__': , '__dict__': , '__weakref__': , '__doc__': None}
Person
(,)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'giveRaise', 'lastName']
------------------------------
{'__module__': '__main__', '__init__': , 'giveRaise': , '__doc__': None}
Manager
(,)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'giveRaise', 'lastName']
'''
class Super_1:
def delegate(self):
self.action()
def action(self):
assert False, 'action must be defined'
class Super_2:
def delegate(self):
self.action()
def action(self):
raise NotImplementedError('action must be defined')
class Sub(Super_1):
def action(self):
print("This is the action")
def main():
# X = Super_1()
# X.delegate() # AssertionError: action must be defined
# Y = Super_2()
# Y.delegate() # NotImplementedError: action must be defined
Z = Sub()
Z.delegate()
if __name__ == "__main__":
main()
'''
输出:
This is the action
'''
from abc import ABCMeta, abstractmethod
class Super(metaclass=ABCMeta):
def delegate(self):
self.action()
@abstractmethod
def action(self):
pass
class Sub(Super):
def action(self):
print("This is the action")
def main():
# X = Super() # TypeError: Can't instantiate abstract class Super with abstract methods action
# X.delegate()
Y = Sub()
Y.delegate()
if __name__ == "__main__":
main()
'''
输出:
This is the action
'''
class C1:
def meth1(self): self.__x = 88
def meth2(self): print(self.__x)
class C2:
def metha(self): self.__x = 99
def methb(self): print(self.__x)
class C3(C1, C2):
pass
def main():
I = C3()
I.meth1()
I.metha()
print(I.__dict__)
I.meth2()
I.methb()
if __name__ == "__main__":
main()
'''
输出:
{'_C1__x': 88, '_C2__x': 99}
88
99
'''
以上,欢迎各位读者朋友提出意见或建议。
欢迎阅读笔者后续博客,各位读者朋友的支持与鼓励是我最大的动力!
written by jiong
时穷节乃见,
一一垂丹青。