Python 中的类
- 一 、类和对象
- 1.概念
- 2.写法:
- 二、 self用法详解
- 1.self代表类的实例,而非类
- 2.self可以不写吗?
- 3.在继承时,self的使用。
- 三、 属性限制访问
- 1. 系统定义
- 2.保护类型成员
- 3.私有类型成员
一 、类和对象
1.概念
类是封装对象的属性和行为的载体,具有相同属性和行为的实体被称为类;这是一个抽象的概念。对象就是把一个抽象的类进行了具体化,具体化的结果叫对象,这个过程叫实例化。
2.写法:
class 后面紧跟类名,即 Person,类名通常大写字母开头,紧接着是(object),表示该类是从哪个类继承下来的,通常,如果没有合适的继承类,就使用 object 类,这是所有类最终都会继承的类。在类中我定义了一个MyName() method(方法)。
class People(object):def __init__(self,name,site) -> None:self.name = nameself.site = sitedef MyName(self):print("My name is {} and my site is {}".format(self.name,self.site))Ann = People('Ann',1)
Ann.MyName()
这里的Ann是People()类的实例,也是一个对象。
**_init_()**是一个特殊方法,类创建时会自动执行它,它必须包含一个self参数且该参数位于第一个;self参数指向实例本身的引用,用于访问类中的属性和方法。方法在调用是自动传递实际参数self。
注意:
(1) 、__init__方法的第一参数永远是self,表示创建的类实例本身,因此,在__init__方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身。
(2)、有了__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,但self不需要传,Python解释器会自己把实例变量传进去:
二、 self用法详解
1.self代表类的实例,而非类
class Test:def ppr(self):print(self)print(self.__class__)t = Test()
t.ppr()
执行结果:
<__main__.Test object at 0x000000000284E080>
<class '__main__.Test'>
从上面的例子中可以很明显的看出,self代表的是类的实例。而self.__class__则指向类。
注意:把self换成this,结果也一样,但Python中最好用约定俗成的self。
2.self可以不写吗?
在Python解释器的内部,当我们调用t.ppr()时,实际上Python解释成Test.ppr(t),也就是把self替换成了类的实例。
class Test:def ppr():print(self)t = Test()
t.ppr()
代码结果:
Traceback (most recent call last):File "cl.py", line 6, in <module>t.ppr()
TypeError: ppr() takes 0 positional arguments but 1 was given
运行时提醒错误如下:ppr在定义时没有参数,但是我们运行时强行传了一个参数。由于上面解释过了t.ppr()等同于Test.ppr(t),所以程序提醒我们多传了一个参数t。这里实际上已经部分说明了self在定义时不可以省略。当然,如果我们的定义和调用时均不传类实例是可以的,这就是类方法。
class Test:def ppr():print(__class__)Test.ppr()运行结果:
<class '__main__.Test'>
3.在继承时,self的使用。
class Parent:def pprt(self):print(self)class Child(Parent):def cprt(self):print(self)
c = Child()
c.cprt()
c.pprt()
p = Parent()
p.pprt()
运行结果:
<__main__.Child object at 0x0000000002A47080>
<__main__.Child object at 0x0000000002A47080>
<__main__.Parent object at 0x0000000002A47240>
解释:
运行c.cprt()时应该没有理解问题,指的是Child类的实例。
但是在运行c.pprt()时,等同于Child.pprt©,所以self指的依然是Child类的实例,由于self中没有定义pprt()方法,所以沿着继承树往上找,发现在父类Parent中定义了pprt()方法,所以就会成功调用。
三、 属性限制访问
Python并没有对方法和属性的访问权限进行限制;可以方法或属性前面加单下划线、双下划线,可以在首尾加双下划线:
1. 系统定义
首尾双下划线表示定义特殊方法,一般是系统定义名字。如:
__init__
2.保护类型成员
以单下划线开头的表示protected(保护)类型的成员,只允许类本身和子类进行访问,但不能使用“from module import ”语句导入。
class Swan:_neck_swan='天鹅类' # 保护属性def __init__(self):print("__init__():",Swan._neck_swan) # 在实例方法中访问保护属性
swan=Swan() # 创建Swan实例
print("直接访问:",Swan._neck_swan) #保护属性可以通过类名访问
print("直接访问:",swan._neck_swan) #保护属性可以通过实例名访问
3.私有类型成员
双下划线表示private(私有)类型成员,只允许定义该方法的类本身进行访问,而且不能通过类的实例进行访问,但是可以通过“类的实例名.__类名__xxx”方式访问
class Swan:__neck_swan='天鹅类' # 私有属性def __init__(self):print("__init__():",Swan.__neck_swan) # 在实例方法中访问私有属性
swan=Swan() # 创建Swan实例
print("加入类名:",swan._Swan__neck_swan) # 私有属性可以通过“类的实例名._类名__xxx”方式访问
print("直接访问:",swan.__neck_swan) # 私有不能属性可以通过实例名访问,会报错
若有不足指出,请多多包涵!!!
若有疑问可以在评论区留言,一起学习一起进步