面向对象-类的定义,成员,方法

类的定义

class 关键字 + 类名(一般首字母大写,驼峰命名法)+()括号内部为父类也称基类、用逗号分隔。

class Car(object):
    def infor(self):
        print('This is a car')

实例化对象,”对象名.成员“的方法来访问其中的数据成员或成员方法。

>>>car = Car()      #实例化对象
>>>car.infor()      #调用对象的成员方法
This is a car

可以使用内置函数isinstance()来测试一个对象是否为某个类的实例,或使用内置函数type()查看对象类型。

>>>isinstance(car,Car)
True
>>>type(car)
__main__.Car

可以使用pass关键字来在类和函数的定义或者选择结构中,表示空语句。临时使用pass来占位。

>>>class Test:
       '''This is only a test.'''
       pass
>>>Test.__doc__
'This is only a test.'

类成员与实例成员

属于实例的数据成员一般是指在构造函数__init__()中定义的,定义和使用时必须以self作为前缀;属于类的数据成员是在类中所有方法之外定义的。

在主程序中(或类的外部),实例属性属于实例(对象),只能通过对象名访问;而类属性属于类,可以通过类名或对象名都可以访问。

在实例方法中可以调用该实例的其他方法,也可以访问类属性以及实例属性

在Python中比较特殊的是,可以动态地为自定义类和对象增加删除成员,这一点是和很多面向对象程序设计语言不同的,也是Python动态类型特点的一种重要体现

class Car:
    price = 100000                     #定义类属性
    def __init__(self, c):
        self.color = c                 #定义实例属性

car1 = Car("Red")                      #实例化对象
car2 = Car("Blue")
print(car1.color, 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)

私有成员与公有成员

私有成语在类的外部不能直接方位,一般是在类内部进行访问和操作,或者在类的尾部通过调用对象的公有成员方法来访问,儿公有成员是可以公开使用的,既可以在类的内部进行方位,也可以在外部程序中使用。

成员名以两个(或更多)下划线开头但不以两个或更多下划线结束侧表示是私有成语,否则不是私有成语。Python没有对私有成语提供严格的访问保护机制,通过“对象名._类名__xxx”也可以在外部程序中国访问私有成员,不建议这样做。

>>> 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,self.__value2)
>>> a = A()
>>> a._value1				#外部可以直接方问私有成员
0
>>> a._A__value2			#在外部方位对象的私有数据成员
0

可以使用内置函数dir()来查看指定对象,模块或命名空间的所有成员。

>>> dir(car)
['__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__', 'infor']

在Python中高一下划线开头或结尾的成员名哟特殊含义。

  1. _xxx:以一个下划线开头,保护成员,只有类对象和子类对象可以访问这些成员,在类的外部一般不建议直接方位;在模块中使用一个或多个下划线开头的成员不能from module import * 导入,除非在模块中使用__all__变量明确致命这样的成员可以被导入。
  2. __xxx__:前后连个下划线,系统定义的特殊成员。
  3. __xxxx:以两个或多个下划线开头但不以其结尾,表示私有成员。一把只有类对象自己能访问,子类对象也不能访问该成员,但在对象外部可以通过“对象名._类名__xxx" 这样的特殊方式来访问。

数据成员

  • 对象数据成员:一般在构造方法__init__()中定义,当然也可以在其他成员方法中定义,在定义和在实例方法中访问该数据成员事以self作为前缀,同一个类的不通对象(实例)的数据成员之间互不影响。

  • 类数据成员:该类所有对象共享的,不属于任何一个对象,在定义类时这类数据成员一般不在任何一个成员方法定义中。在主程序中或在类的外部,对象数据成员属于实例(对象),只能通过对象名访问;而类数据成员属于类,可以通过类名或对象名访问。

利用类数据成员的共享性,可以适时获得该类的对象数量,并且可以控制该类可以创建的对象最大数量。例如:

>>> class Demo(object):
...     total=0
...     def __new__(cls,*arg,**kwargs):
...             if cls.total>=3:
...                     raise Exception('最多只能创建3个对象')
...             else:
...                     return object.__new__(cls)
...     def __init__(self):
...             Demo.total=Demo.total+1
...
>>> t1 = Demo()
>>> t2 = Demo()
>>> t3 = Demo()
>>> t4 = Demo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in __new__
Exception: 最多只能创建3个对象

方法

Python的成员方法大致可以分为公有方法,私有方法,静态方法,类方法和抽象方法这几种类型。

所有实例方法(包括公有方法,私有方法,抽象方法和某些特殊方法)都必须至少有一个名为self的参数

类的所有实例方法都必须至少有一个名为self的参数,并且必须是方法的第一个形参(如果有多个形参的话),self参数代表将来要创建的对象本身。

在类的实例方法中访问实例属性时需要以self为前缀。

在外部通过对象调用对象方法时并不需要传递这个参数,如果在外部通过类调用对象方法则需要显式为self参数传值。

>>> class Car(object):
...     def show(self):
...             print('hello')
>>> car = Car()
>>> car.show()
hello

如果在外部通过类名调用属于对象的公有方法,需要显式为该方法的self 参数传递一个对象名,用来明确指定访问哪个对象的成员。

静态方法和类方法都可以通过类名和对象名调用,但不能直接访问属于对的成员,只能访问属于类的成员。另外,静态方法和类方法不属于任何实例,不会绑定到任何实例,也不依赖于任何实例的状态,与实例方法相比能减少很多开销,类方法一般以 cls 作为第一个参数表示该类自身,在调用类方法时不需要为该参数传递值,静态方法则可以不接收任何参数。

>>> class Root:
        __total = 0
        def __init__(self,v):					#构造方法,特殊方法
            self.__value = v					
            Root.__total += 1					
        def show(self):							#普通实例方法,一般以self作为第一个参数的名字
            print('self.__value:',self.__value)
            print('Root.__total:',Root.__total)
        @classmethod							#修饰器,声明类方法
        def classShowTotal(cls):				 #类方法,一般以cls作为第一个参数的名字
            print(cls.__total)
        @staticmethod							#修饰器,声明静态方法
        def staticShowTotal():					 #静态方法,可以没有参数
            print(Root.__total)
>>>r = Root(3)
>>>r.classShowTotal()							#通过对象来调用类方法
1
>>>r.staticShowTotal()							#通过对象来调用静态方法
1
>>>rr = Root(5)
>>>Root.classShowTotal()
2
>>>Root.staticShowTotal()
2
>>>Root.show()									#试图通过类名直接调用实例方法,失败
TypeError                                 Traceback (most recent call last)
TypeError: show() missing 1 required positional argument: 'self'
>>>Root.show(rr)								#可以通过这种方法来调用方法并访问实例成员
self.__value: 5
Root.__total: 2

抽象方法一般在抽象类中定义,并且要求在派生类中必须重新实现,否则不允许派生类创建实例。

import abc
class Foo(metaclass = abc.ABCMeta):					#抽象类
    def f1(self):								   #普通实例方法
        print(123)
    def f2(self):								   #普通实例方法
        print(456)
    @abc.abstractmethod							    #抽象方法
    def f3(self):
        raise Exception('You must reimplement this method.')
class Bar(Foo):
    def f3(self):								   #必须重新实现基类中的抽象方法
        print(33333)
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值