在初学Python过程中,会遇到这样的概念,一个类下面会有多个方法,有的叫类方法、有的叫静态方法,还有的叫实例方法。当调用他们的时候,不免会有点蒙圈,那么他们之间的区别是什么呢?
和类属性一样, 类方法可以进行细致地划分为类方法、实例方法和静态方法。
表象区别就是:
- 类方法前用@classmethod修饰
- 静态方法前用@staticmethod修饰
- 不加任何修饰的就是实例方法(普通方法)
-用法区别-
实例方法
也是普通方法,实例方法是我们最常用的方法,它定义时最少要包含一个self参数,用于绑定调用此方法的实例对象(所谓绑定,即用实例调用的时候,不需要显式的传入)。
换句话说,当实例调用方法的时候,会默认将实例本身传入到这个参数self,而当类直接调用时,因为本身类型是一个class,不是实例对象,所以报错。
如果非要用类直接调用,需要手动传入一个实例作为第一个参数。注意:若随便传入一个字符串的话,也不会报错,但是会造成程序紊乱,因此不推荐这种调用方式。
用如下这段代码举例说明:
class A(object):
def instance_method(self, X):
print(f'instance_method :{X} : {self}')
a = A()
A.instance_method('x')
A.instance_method(a, 'x')
A.instance_method('strs', 'x')
a.instance_method('a')
代码中 instance_method 为实例方法,而第6行类A调用了此方法,而实例方法默认传入的应该是实例,而不是类,因此将x当做实例传给了默认的self,此时实例方法还缺少一个参数没有传入,导致报错:TypeError: instance_method() missing 1 required positional argument: ‘x’。
- 第7行纠正了第6行的做法,传入了实例a,且传入了一个参数x,所以不会报错,self就是A的实例a。
- 第8行将字符串代替实际的实例a传入self,虽不会报错,但是对于程序毫无价值,不推荐这样使用,没有意义。
- 第9行是最常用的方法,实例a调用了实例方法,默认将实例a传入了self,再将参数x传入了X,完整实现了调用。
本地方法
就当做实例方法的一种吧,好奇心的驱使,如果实例方法没有添加self这个参数呢,为了区分,我们且叫他”本地方法”。所谓本地,也就是实例无法调用,只能类自己调用。
class A(object):
def local_method():
print(f'local_method')
def local_method2(strs):
print(f'local_method2')
a = A()
a.local_method()
a.local_method2()
A.local_method()
如上代码,第2行的local_method()就是个本地方法,而此时在第9行实例a调用这个本地方法的时候,由于程序会默认将实例a传入参数self,但是本地方法没有写self,因此报错:TypeError: A.local_method() takes 0 positional arguments but 1 was given。
再看第5行的实例方法,为什么叫实例方法,明明没有self啊?这里要特别说明下,self只是约定俗成的写法,实际上随便写个什么字符串都可以的。因此第10行实例a调用实例方法,不会报错,程序正常执行。
第11行类A调用本地方法,也是不会报错的。但如果类A调用实例方法就和第一节讲的报错了。
类方法
类方法有一个特点,就是这个方法必须要有@classmethod来修饰。和实例方法类似,至少也要传一个参数,约定俗称为cls,Python会自动将类本身绑定到这个参数上面。
类方法通常使用类直接调用,也可以用实例调用(不推荐)。当实例调用的时候,Python会将实例的最底层类(即实例直接所属类)型传入cls参数中。
class A(object):
name = 'I am Class A'
@classmethod
def class_method(cls, s):
print(cls.name) # 可以访问类成员print(cls.name) # 可以访问类成员
print(f"class_method : {cls} :: {s}")
class B(A):
name = 'I am Class B'
a = A()
b = B()
A.class_method('I am class')
a.class_method('I am instance')
B.class_method('I am B class')
b.class_method('I am b instance')
如上代码,B类继承了A类,并复写了name属性,而此时A类中的方法就是类方法,有两个参数,一个是默认的类参数cls,还有一个普通入参。
- 第14行,A类直接调用自己的类方法,默认将自己传入了cls,并将括号中的字符串传给了参数s,用得恰到好处。此时第6行打印”I am Class A”可以看出,cls确实是传的A。
- 第15行用A的实例a调用类方法,会默认将a的直属类(也就是A)传到cls中,因此效果和A调用是一样的。
- 第16行用继承类B调用的父类的类方法,既然是继承,那么程序传入的就是类B到cls中,由于B类中对name做了复写,因此第6行打印出来的就是”I am Class B”。
- 第17行用继承类B的实例b调用的父类的类方法,按照上述规则,是传入的b的直属类到cls中,也就是将B传入了cls中,而不是A(这边要注意区别),因此和B调用是一样的。
静态方法
静态方法是使用@staticmethod修饰的方法,它不能访问任何类属性和类方法,因为它不含self或cls这些特殊参数,因此也无法访问类或实例中的成员。
也就是说,Python没有给他绑定实例或者类,要想使用,只能当参数来传,所以在静态方法中的入参都是普通参数,严格来讲,上面说的本地方法应该也要写成静态方法。
class A(object):
@staticmethod
def static_method(a, b):
print(f"static_method : {a} + {b}")
a = A()
A.static_method('aa', 'bb')
a.static_method('aa', 'bb')
(左右滑动查看完整代码)
如上代码中,尽管第7行类A调用了方法,但是由于是静态方法,访问不了类属性,因此不会将类A传入所谓的cls中,静态方法中也没有cls这个参数,因此它的参数都是普通入参。
第8行的实例调用也是和A一样的效果。
所以逻辑上讲,类方法应当只被类调用,实例方法只被实例调用,静态方法两者都能调用,主要区别在于参数传递上的区别。
实例方法悄悄传递的是self引用作为参数,而类方法悄悄传递的是cls引用作为参数。
要记住几点
1.实例调用实例方法和本地方法时,Python默认将实例本身作为第一个参数传入。
2.实例调用类方法时,Python默认将实例的最底层类作为第一个参数传入。
3.实例调用静态方法时,Python啥也不传,需要几个参数就要传几个参数。
4.类调用类方法时,Python默认将类本身作为第一个参数传入。
5.类调用非类方法时,Python啥也不传,需要几个参数就要传几个参数。
【python学习】
学Python的伙伴,欢迎加入新的交流【君羊】:740587468
一起探讨编程知识,成为大神,群里还有软件安装包,实战案例、学习资料
Original: https://blog.csdn.net/weixin_56659172/article/details/127817209
Author: 爱摸鱼的菜鸟码农.
Title: Python类的多种方法,你分得清吗?
相关阅读
Title: 求关系模式r的所有候选码_关系数据库理论
今天,我想和大家分享我对关系数据库理论的思考
[En]
Today, I want to share with you my thoughts on relational database theory
正如我们所知,当今的数据库通常使用关系模型来设计数据库。当然,在讨论关系数据库之前,我将讨论数据库中的数据模型
[En]
As we know, today’s databases generally use relational models to design databases. Of course, before talking about relational databases, I’ll talk about the data models in databases
一.数据模型
在数据库中,数据模型分为概念模型和数据模型
1.概念模型:是按用户观点来对数据和信息建模,只考虑实体和实体之间的关系以及实体的属性
其中,实体型可以类比与java中类的概念,如:学生(学号,姓名,年龄…)就是一个实体型
而实体之间的联系就可分为三类:
E-R模型
既然有了概念模型,固然就需要一定的规范来表示概念模型,而E-R模型则是一种对概念模型的表示方法,具体内容小编在这里就不多阐述,可以去网上查阅,以下便是小编之前做过E-R模型:
2.数据模型
这里的数据模型是指从计算机的角度对数据进行建模,包括数据结构、数据操作和数据约束
[En]
The data model here refers to the modeling of data from the perspective of computer, which consists of data structure, data operation and data constraints
在这里小编主要谈及其中的三类:
(1)层次模型;可以类比数据结构中树
(2)网状模型:可以类比数据结构中的图
(3)关系模型:由关系数据结构、关系操作集合、关系完整性约束三部分组成
其中
- 关系数据结构:可以理解为一张二维表
- 关系操作集:分为查询和更新。它的特点是操作集的方式,即操作对象和结果都是集。我在这里就不多说了
[En]
Relational operation set: it is divided into query and update. It is characterized by the way of operation set, that is, both the operation object and the result are sets. I will not elaborate too much here*
- 关系完整性约束:分为实体完整性(一个表必须有一个主键才能唯一地标识每一行:例如,您的ID号是可以唯一标识您的所有信息)、引用完整性(其中一个表引入另一个表的主键,称为外键,具体内容可以在线查看)、,和用户定义的完整性
[En]
Relationship integrity constraints: divided into entity integrity (a table must have a primary key to uniquely identify each line: for example, your ID number number is all the information that can uniquely identify you), referential integrity (one table introduces the primary key of another table, which is called a foreign key, and specific content can be viewed online), and user-defined integrity*
二.关系数据库理论
R(U,D,DOM,F):
- R:关系名
- U:关系中属性名的集合
- D:属性中属性值所来自的域
- Dom:属性向域的映像集合
- F:属性间数据依赖的集合
1. 数据依赖 :
分为:
- 函数依赖:
(1)定义:设R(U)是属性集U上的关系模式(就是指一张表的表头),其中属性X,Y

U,若满足对于任意两个不同的行,其X相同,必定有其Y相同,则称Y函数依赖于X,即X

Y。
如果X相同,而两个的Y不同,则称Y不函数依赖于X
(2)分类:
- 平凡的函数依赖:若X
Y,且Y
X,则称X
Y为平凡的函数依赖
-
非平凡的函数依赖:若X
Y,且Y不包含于 X,则称X
Y为平凡的函数依赖
-
完全函数依赖:若X
Y,对
X的真子集X1,都有X1
Y,则称为完全函数依赖
-
部分函数 依赖:若X
Y,对
X的真子集X1,有Y不函数依赖于X1,则称为部分函数依赖
-
传递函数 依赖:若X
Y(Y不包含于X),X不函数依赖于Y,而Y
Z,则称Z对X传递函数依赖
-
直接函数 依赖 :若X
Y,Y
X,而Y
Z,则Z对X直接函数依赖
-
由函数定义的码:设K为R(U,F)中的属性或属性组
(1)候选码:若U中所有属性完全函数依赖于K,则K为候选码
(2)主码:若有多个候选码,则从中选出一个作为主码
(3)主属性:包含在任一一个候选码中的属性
(4)非主属性:除主属性以外的属性则为非主属性
(5)全码:所有属性构成了主码
2.范式(NF)
- 1NF:关系中每一个分量不可再分。其实一般来说,一张二维表就是已经属于1NF
- 2NF:R
1NF,同时表中的每个非主属性完全依赖于码,即不允许有非主属性对码有部分依赖
- 3NF:R
2NF,且不存在非主属性对码的传递依赖
- BCNF:R
3NF,且保证每一个函数依赖中,决定因素必然是候选码,如存在X
Y,那么,必须要X是R中候选码。不满足BCNF的缘由:存在主属性对码的不良依赖,如传递依赖,部分依赖等
- 4NF: 关系模式R< U , F >
1NF,若对于每一个是非平凡的多值依赖X
Y(Y不包含于X),X都含有码,则称R
4NF。
3.多值依赖
这里我不详细说明具体的定义,因为它更抽象,所以不方便描述。这里,我给你举个例子
[En]
I won’t elaborate on the specific definition here, because it is more abstract, so it is inconvenient to describe. Here, I’ll give you an example
由表可知,A1,与属性B和C中满足
A2同样也满足,则称A

B,A

C其中可以看到,A中:A1,A2,B中:B1,C中:C1,C2,C3,三者中,Ci尽管会有B的属性,但是其仅仅决定于A
故定义:关系模式R(U),X、Y、Z

U,并且Z = U – X – Y,若对R(U)的任一关系r,对给定的一对(x,z)值有一组Y的值,这组值仅仅决定于x值而与z值无关,则称Y多值依赖于X,记作:X

Y。
如例子中所示,如果此时B属性值中增加了B2值,则若要继续保持A

B,A

C,则在表中必然有这样的关系:
我只是在这里简要描述了关系数据库的理论。当然,内容远不止于此。在这里,我们还将涉及到函数依赖、关系模式分解等公理系统。我在这里写的内容基本上可以理解关系数据库理论的基本部分。
[En]
I just briefly describe the theory of relational database here. Of course, the content is far more than that. Here, we will also involve the axiom system of functional dependency, relational schema decomposition, etc. You can carefully understand the details. What I write here can basically understand the basic part of relational database theory.
Original: https://blog.csdn.net/weixin_39859055/article/details/113367425
Author: weixin_39859055
Title: 求关系模式r的所有候选码_关系数据库理论
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/207348/
转载文章受原作者版权保护。转载请注明原作者出处!