Python小记——面向对象程序设计

mac2024-04-18  37

菜鸟教程 面向对象

样例

In [1]: class A(object): ...: def __init__(self, v): ...: self.value = v ...: def show(self): ...: print(self.value) ...: In [2]: a = A(3) In [3]: a.show() 3

在Python中比较特殊的是,可以动态地为类和对象增加成员

class Car: price = 100000 #定义类属性 def __init__(self, c): self.color = c #定义实例属性 car1 = Car("Red") #实例化对象 car2 = Car("Blue") print(car1.color) #查看实例属性 print(Car.price) #查看类属性的值 Car.price = 110000 #修改类属性 Car.name = 'QQ' #动态增加类属性 car1.color = "Yellow" #修改实例属性 print(car2.color, Car.price, Car.name) print(car1.color, Car.price, Car.name) import types def setSpeed(self, s): self.speed = s car1.setSpeed = types.MethodType(setSpeed, car1) #动态增加成员方法 car1.setSpeed(50) #调用成员方法 print(car1.speed) >>> import types >>> class Person(object): def __init__(self, name): assert isinstance(name, str), 'name must be string' self.name = name >>> def sing(self): print(self.name+' can sing.') >>> def walk(self): print(self.name+' can walk.') >>> def eat(self): print(self.name+' can eat.') >>> zhang = Person('zhang') >>> zhang.sing() #用户不具有该行为 AttributeError: 'Person' object has no attribute 'sing' >>> zhang.sing = types.MethodType(sing, zhang) #动态增加一个新行为 >>> zhang.sing() zhang can sing. >>> zhang.walk() AttributeError: 'Person' object has no attribute 'walk' >>> zhang.walk = types.MethodType(walk, zhang) >>> zhang.walk() zhang can walk. >>> del zhang.walk #删除用户行为 >>> zhang.walk() AttributeError: 'Person' object has no attribute 'walk'

函数和方法是有区别的

>>> class Demo: pass >>> t = Demo() >>> def test(self, v): self.value = v >>> t.test = test >>> t.test #普通函数 <function test at 0x00000000034B7EA0> >>> t.test(t, 3) #必须为self参数传值 >>> t.test = types.MethodType(test, t) >>> t.test #绑定的方法 <bound method test of <__main__.Demo object at 0x000000000074F9E8>> >>> t.test(5) #不需要为self参数传值

方法

在类中定义的方法可以粗略分为四大类:公有方法、私有方法、静态方法和类方法。公有方法、私有方法都属于对象,私有方法的名字以两个下划线“__”开始,每个对象都有自己的公有方法和私有方法,在这两类方法中可以访问属于类和对象的成员; 公有方法通过对象名直接调用,私有方法不能通过对象名直接调用,只能在属于对象的方法中通过 self 调用或在外部通过 Python 支持的特殊方式来调用。 如果通过类名来调用属于对象的公有方法,需要显式为该方法的 self 参数传递一个对象名,用来明确指定访问哪个对象的数据成员。类变量:属于类本身,用于定义该类本身所包含的状态数据实例变量:属于该类的对象,用于定义对象所包含的状态数据方法:定义该类的对象的行为或功能的实现 >>> class Root: """这是一个类""" #类定义说明文档 __total = 0 #类变量在整个实例化的对象中是公用的。类变量通常不作为实例变量使用 def __init__(self, v): #构造方法 value = 0 #局部变量 self.__value = v #实例变量 Root.__total += 1 #通过类来访问类变量 def show(self): #普通实例方法 print('self.__value:', self.__value) print('Root.__total:', Root.__total) @classmethod #修饰器,声明类方法 def classShowTotal(cls): #类方法 print(cls.__total) @staticmethod #修饰器,声明静态方法 def staticShowTotal(): #静态方法 print(Root.__total) >>> r = Root(3) >>> r.classShowTotal() #通过对象来调用类方法 1 >>> r.staticShowTotal() #通过对象来调用静态方法 1 >>> r.show() self.__value: 3 Root.__total: 1 >>> rr = Root(5) >>> Root.classShowTotal() #通过类名调用类方法 2 >>> Root.staticShowTotal() #通过类名调用静态方法 2 >>> Root.show() #试图通过类名直接调用实例方法,失败 TypeError: unbound method show() must be called with Root instance as first argument (got nothing instead) >>> Root.show(r) #但是可以通过这种方法来调用方法并访问实例成员 self.__value: 3 Root.__total: 2 >>> Root.show(rr) #通过类名调用实例方法时为self参数显式传递对象名 self.__value: 5 Root.__total: 2

对象是类的实例。

对于类变量而言,它们就是属于在类命名空间内定义的变量,因此程序不能直接访问这些变量,程序必须使用类名/对象来调用类变量。通过对象访问类变量,本质上依然是通过类名在访问。

如果程序对一个对象的实例变量进行了修改,这种修改也不会影响到类变量和其他对象的实例变量。

创建对象的根本方法是构造方法,调用某个类的构造方法即可创建这个类的对象,Python无需使用new方法。

self 不是 python 关键字

在使用类调用实例方法的时候,Python不会自动为第一个参数绑定调用者。

u = User() User.walk(u) <=> u = User() u.walk()

Python只要求手动为第一个参数绑定参数值,并不要求必须绑定User对象,User.walk(“asd”)也可。

当Python对象的一个方法调用另一个方法时,不可以省略self。

类方法的第一个参数(通常为cls)会自动绑定到类本身,但是对于静态方法则不会自动绑定。

静态方法和类方法都可以通过类名和对象名调用,但不能直接访问属于对象的成员,只能访问属于类的成员。

静态方法可以没有参数。

一般将cls作为类方法的第一个参数名称,但也可以使用其他的名字作为参数,并且在调用类方法时不需要为该参数传递值。

在使用Python编程时,一般不需要使用类方法或静态方法,程序完全可以使用函数来代替类方法或静态方法。但是在特殊的场景(比如工程模式),类方法和静态方法也是不错的选择。

类的专有方法

私有成员和公有成员

>>> class A: def __init__(self, value1 = 0, value2 = 0): self._value1 = value1 self.__value2 = value2 def setValue(self, value1, value2): self._value1 = value1 self.__value2 = value2 def show(self): print(self._value1) print(self.__value2) >>> a = A() >>> a._value1 0 >>> a._A__value2 #在外部访问对象的私有数据成员 0 在Python中,以下划线开头的变量名和方法名有特殊的含义,尤其是在类的定义中。用下划线作为变量名和方法名前缀和后缀来表示类的特殊成员: _xxx:受保护成员,不能用’from module import *'导入; __xxx__:系统定义的特殊成员; __xxx:私有成员,只有类对象自己能访问,子类对象不能直接访问到这个成员,但在对象外部可以通过“对象名._类名__xxx”这样的特殊方式来访问。 注意:Python中不存在严格意义上的私有成员。 In [8]: class Fruit(object): ...: value = 1 ...: def __init__(self): ...: self.__color = 'Red' ...: self._num = 0.1 ...: self.price = 1 ...: def show(self): ...: print("value:{},color:{},num:{},price:{}".f ...: ormat(self.value, self.__color, self._num, self.pri ...: ce)) ...: In [9]: f = Fruit() In [10]: f.show() value:1,color:Red,num:0.1,price:1 In [11]: f.value Out[11]: 1 In [12]: f.__color ------------------------------------------------------------ AttributeError Traceback (most recent call last) <ipython-input-12-8047530fa8c8> in <module> ----> 1 f.__color AttributeError: 'Fruit' object has no attribute '__color' In [13]: f._num Out[13]: 0.1 In [14]: f.price Out[14]: 1 >>> class Fruit: def __init__(self): self.__color = 'Red' self.price = 1 >>> apple = Fruit() >>> apple.price #显示对象公开数据成员的值 1 >>> apple.price = 2 #修改对象公开数据成员的值 >>> apple.price 2 >>> print(apple.price, apple._Fruit__color) #显示对象私有数据成员的值 2 Red >>> apple._Fruit__color = "Blue" #修改对象私有数据成员的值 >>> print(apple.price, apple._Fruit__color) 2 Blue >>> print(apple.__color) #不能直接访问对象的私有数据成员,出错 AttributeError: Fruit instance has no attribute '__color'

运算符重载

#!/usr/bin/python3 class Vector: def __init__(self, a, b): self.a = a self.b = b def __str__(self): return 'Vector (%d, %d)' % (self.a, self.b) def __add__(self,other): return Vector(self.a + other.a, self.b + other.b) v1 = Vector(2,10) v2 = Vector(5,-2) print (v1 + v2) In [18]: v1 + v2 Out[18]: <__main__.Vector at 0x1f935fa5cf8> Vector(7,8)

在程序中,可以使用一个下划线来表示不关心该变量的值。

>>> for _ in range(5): print(3, end=' ') 3 3 3 3 3 >>> a, _ = divmod(60, 18) #只关心整商,不关心余数,等价于a = 60//18 >>> a 3

属性

将属性设置为可读、可修改、可删除。

class Test: def __init__(self, value): self.__value = value def __get(self): return self.__value def __set(self, v): self.__value = v def __del(self): del self.__value value = property(__get, __set, __del) def show(self): print(self.__value) >>> t = Test(3) >>> t.show() 3 >>> t.value 3 >>> t.value = 5 >>> t.show() 5 >>> t.value 5 >>> del t.value #删除属性 >>> t.value #对应的私有数据成员已删除 AttributeError: 'Test' object has no attribute '_Test__value' >>> t.show() AttributeError: 'Test' object has no attribute '_Test__value' >>> t.value =1 #为对象动态增加属性和对应的私有数据成员 >>> t.show() 1 >>> t.value 1
最新回复(0)