当前位置:   article > 正文

Python 中的类,包括self关键字、类的属性限制访问_self 类

self 类

一 、类和对象

1.概念

类是封装对象的属性和行为的载体,具有相同属性和行为的实体被称为类;这是一个抽象的概念。对象就是把一个抽象的类进行了具体化,具体化的结果叫对象,这个过程叫实例化

2.写法:

class 后面紧跟类名,即 Person,类名通常大写字母开头,紧接着是(object),表示该类是从哪个类继承下来的,通常,如果没有合适的继承类,就使用 object 类,这是所有类最终都会继承的类。在类中我定义了一个MyName() method(方法)。

class People(object):
    def __init__(self,name,site) -> None:
        self.name = name
        self.site = site

    def MyName(self):
        print("My name is {} and my site is {}".format(self.name,self.site))

Ann = People('Ann',1)
Ann.MyName()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这里插入图片描述
这里的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'>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

从上面的例子中可以很明显的看出,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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

代码结果:

Traceback (most recent call last):
  File "cl.py", line 6, in <module>
    t.ppr()
TypeError: ppr() takes 0 positional arguments but 1 was given
  • 1
  • 2
  • 3
  • 4

运行时提醒错误如下:ppr在定义时没有参数,但是我们运行时强行传了一个参数。由于上面解释过了t.ppr()等同于Test.ppr(t),所以程序提醒我们多传了一个参数t。这里实际上已经部分说明了self在定义时不可以省略。当然,如果我们的定义和调用时均不传类实例是可以的,这就是类方法。

class Test:
    def ppr():
        print(__class__)

Test.ppr()

运行结果:
<class '__main__.Test'>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

运行结果:

<__main__.Child object at 0x0000000002A47080>
<__main__.Child object at 0x0000000002A47080>
<__main__.Parent object at 0x0000000002A47240>
  • 1
  • 2
  • 3

解释:
运行c.cprt()时应该没有理解问题,指的是Child类的实例。
但是在运行c.pprt()时,等同于Child.pprt©,所以self指的依然是Child类的实例,由于self中没有定义pprt()方法,所以沿着继承树往上找,发现在父类Parent中定义了pprt()方法,所以就会成功调用。

三、 属性限制访问

Python并没有对方法和属性的访问权限进行限制;可以方法或属性前面加单下划线、双下划线,可以在首尾加双下划线:

1. 系统定义

首尾双下划线表示定义特殊方法,一般是系统定义名字。如:

__init__
  • 1

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)  #保护属性可以通过实例名访问
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述

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)  # 私有不能属性可以通过实例名访问,会报错
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述

若有不足指出,请多多包涵!!!
若有疑问可以在评论区留言,一起学习一起进步
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/883388
推荐阅读
相关标签
  

闽ICP备14008679号