SharpGL学习笔记(十一) 光源创建的综合例子:光源参数可调节的测试场景

灯光的测试例子:光源参数可以调节的测试场景

先看一下测试场景和效果。

场景中可以切换视图, 以方便观察三维体和灯光的位置。环境光,漫射光,镜面反射光都可以在四种颜色间切换。

灯光位置和摄像机位置(LookAt)可以输入数值或者点动调节,也可以按键盘的QEWASD六个键进行调节。

你还会注意到:球体对光的效果要敏感柔和些,而那个六面体BOX看来效果不好。这是因为灯光对顶点发生作用。在程序里面,球休的顶点数量有20*10,而BOX只有4*6个,而且还重合了一些顶点。

这一点,在3dsmax的全局光照里面表现很明显,做为墙壁的box顶点数量越大,计算出来光照效果越好

还有,界面上灯光位置是 -1,5,1,1  前三个是x,y,z, 后面的一个1不是坐标,它取值0或者1,表示灯光是定向光源(directonal),还是定位光源(positional)。

代码如下:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Windows.Forms;
  9 using SharpGL;
 10
 11 namespace SharpGLWinformsApplication1
 12 {
 13
 14     public partial class SharpGLForm : Form
 15     {
 16         private float rotation = 0.0f;
 17         private bool isRotate = false;
 18         private bool isLines = false;
 19         private bool isFrontView = false;
 20         private bool isLeftView = false;
 21         private bool isTopView = false;
 22         private bool isPerspective = true;
 23         private float[] lightPos = new float[] { -1, -3, 1, 1 };
 24         private float[] lightSphereColor = new float[] { 1f, 1f, 1f };
 25         private IList<float[]> lightColor = new List<float[]>();
 26         private double[] lookatValue = { 1, 1, 2, 0, 0, 0, 0, 1, 0 };
 27         private IList<double[]> viewDefaultPos = new List<double[]>();
 28         public SharpGLForm()
 29         {
 30             InitializeComponent();
 31         }
 32
 33         private void openGLControl_OpenGLDraw(object sender, PaintEventArgs e)
 34         {
 35             OpenGL gl = openGLControl.OpenGL;
 36             gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
 37             gl.LoadIdentity();
 38             gl.Rotate(rotation, 0.0f, 1.0f, 0.0f);
 39
 40             drawGrid(gl);
 41             DrawCube(ref gl, 1.5f,-1f, -2f, isLines);
 42             drawOneSphere(ref gl,-3,-2,-4,isLines);
 43             if (isRotate)
 44                 rotation += 3.0f;
 45         }
 46
 47         private void setLightColor(OpenGL gl)
 48         {
 49             gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_AMBIENT, lightColor[0]);
 50             gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_DIFFUSE, lightColor[1]);
 51             gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_SPECULAR, lightColor[2]);
 52         }
 53
 54         private void openGLControl_OpenGLInitialized(object sender, EventArgs e)
 55         {
 56             OpenGL gl = openGLControl.OpenGL;
 57
 58             //四个视图的缺省位置
 59             viewDefaultPos.Add(new double[] { 1, 1, 2, 0, 0, 0, 0, 1, 0 });     //透视
 60             viewDefaultPos.Add(new double[] { 0, 0, 2, 0, 0, 0, 0, 1, 0 });     //前视
 61             viewDefaultPos.Add(new double[] { 5, 0, 0, 0, 0, 0, 0, 1, 0 });     //左视
 62             viewDefaultPos.Add(new double[] { 0, 13, 0, -1, 0, 0, 0, 1, 0 });   //顶视
 63             lookatValue =(double[])viewDefaultPos[0].Clone();
 64
 65             lightColor.Add(new float[] { 1f, 1f, 1f, 1f });  //环境光(ambient light)
 66             lightColor.Add(new float[] { 1f, 1f, 1f, 1f });  //漫射光(diffuse light)
 67             lightColor.Add(new float[] { 1f, 1f, 1f, 1f });  //镜面反射光(specular light)
 68
 69             setLightColor(gl);
 70             gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, lightPos);
 71
 72             gl.Enable(OpenGL.GL_LIGHTING);
 73             gl.Enable(OpenGL.GL_LIGHT0);
 74
 75             gl.ClearColor(0, 0, 0, 0);
 76         }
 77
 78         private void drawOneSphere(ref OpenGL gl, float xPos, float yPos, float zPos, bool isLine)
 79         {
 80             gl.PushMatrix();
 81             {
 82                 gl.Translate(xPos, yPos, zPos);
 83                 gl.Color(lightSphereColor);
 84                 drawSphere(gl,1,20,10,isLine);
 85             }
 86             gl.PopMatrix();
 87         }
 88
 89         private void openGLControl_Resized(object sender, EventArgs e)
 90         {
 91
 92             OpenGL gl = openGLControl.OpenGL;
 93             gl.MatrixMode(OpenGL.GL_PROJECTION);
 94             gl.LoadIdentity();
 95             gl.Perspective(40.0f, (double)Width / (double)Height, 0.01, 100.0);
 96
 97
 98             gl.LookAt(lookatValue[0], lookatValue[1], lookatValue[2],
 99                 lookatValue[3], lookatValue[4], lookatValue[5],
100                 lookatValue[6], lookatValue[7], lookatValue[8]);
101
102             gl.MatrixMode(OpenGL.GL_MODELVIEW);
103             updateLabInfo();
104         }
105
106         internal void DrawCube(ref OpenGL Gl, float xPos, float yPos, float zPos, bool isLine)
107         {
108             Gl.PushMatrix();
109             Gl.Translate(xPos, yPos, zPos);
110             if (isLine)
111                 Gl.Begin(OpenGL.GL_LINE_STRIP);
112             else
113                 Gl.Begin(OpenGL.GL_POLYGON);
114
115             /** 顶面 */
116             Gl.Vertex(0.0f, 0.0f, 0.0f);
117             Gl.Vertex(0.0f, 0.0f, -1.0f);
118             Gl.Vertex(-1.0f, 0.0f, -1.0f);
119             Gl.Vertex(-1.0f, 0.0f, 0.0f);
120
121             /** 前面 */
122             Gl.Vertex(0.0f, 0.0f, 0.0f);
123             Gl.Vertex(-1.0f, 0.0f, 0.0f);
124             Gl.Vertex(-1.0f, -1.0f, 0.0f);
125             Gl.Vertex(0.0f, -1.0f, 0.0f);
126
127             /** 右面 */
128             Gl.Vertex(0.0f, 0.0f, 0.0f);
129             Gl.Vertex(0.0f, -1.0f, 0.0f);
130             Gl.Vertex(0.0f, -1.0f, -1.0f);
131             Gl.Vertex(0.0f, 0.0f, -1.0f);
132
133             /** 左面*/
134             Gl.Vertex(-1.0f, 0.0f, 0.0f);
135             Gl.Vertex(-1.0f, 0.0f, -1.0f);
136             Gl.Vertex(-1.0f, -1.0f, -1.0f);
137             Gl.Vertex(-1.0f, -1.0f, 0.0f);
138
139             /** 底面 */
140             Gl.Vertex(0.0f, 0.0f, 0.0f);
141             Gl.Vertex(0.0f, -1.0f, -1.0f);
142             Gl.Vertex(-1.0f, -1.0f, -1.0f);
143             Gl.Vertex(-1.0f, -1.0f, 0.0f);
144
145
146             /** 后面 */
147             Gl.Vertex(0.0f, 0.0f, 0.0f);
148             Gl.Vertex(-1.0f, 0.0f, -1.0f);
149             Gl.Vertex(-1.0f, -1.0f, -1.0f);
150             Gl.Vertex(0.0f, -1.0f, -1.0f);
151             Gl.End();
152             Gl.PopMatrix();
153         }
154
155         void drawGrid(OpenGL gl)
156         {
157             //绘制过程
158             gl.PushAttrib(OpenGL.GL_CURRENT_BIT);  //保存当前属性
159             gl.PushMatrix();                        //压入堆栈
160             gl.Translate(0f, -2f, 0f);
161             gl.Color(0f, 0f, 1f);
162
163             //在X,Z平面上绘制网格
164             for (float i = -50; i <= 50; i += 1)
165             {
166                 //绘制线
167                 gl.Begin(OpenGL.GL_LINES);
168                 {
169                     if (i == 0)
170                         gl.Color(0f, 1f, 0f);
171                     else
172                         gl.Color(0f, 0f, 1f);
173
174                     //X轴方向
175                     gl.Vertex(-50f, 0f, i);
176                     gl.Vertex(50f, 0f, i);
177                     //Z轴方向
178                     gl.Vertex(i, 0f, -50f);
179                     gl.Vertex(i, 0f, 50f);
180
181                 }
182                 gl.End();
183             }
184             gl.PopMatrix();
185             gl.PopAttrib();
186         }
187
188
189         void drawSphere(OpenGL gl,double radius,int segx,int segy,bool isLines)
190         {
191             gl.PushMatrix();
192             gl.Translate(2f, 1f, 2f);
193             var sphere = gl.NewQuadric();
194             if (isLines)
195                 gl.QuadricDrawStyle(sphere, OpenGL.GL_LINES);
196             else
197                 gl.QuadricDrawStyle(sphere, OpenGL.GL_QUADS);
198             gl.QuadricNormals(sphere, OpenGL.GLU_SMOOTH);
199             gl.QuadricOrientation(sphere, (int)OpenGL.GLU_OUTSIDE);
200             gl.QuadricTexture(sphere, (int)OpenGL.GLU_FALSE);
201             gl.Sphere(sphere, radius, segx, segy);
202             gl.DeleteQuadric(sphere);
203             gl.PopMatrix();
204         }
205
206         private void moveObject(int obj,string keyName)
207         {
208             //obj==0移动视图
209             switch (keyName)
210             {
211                 case "btnQ":
212                     if (obj == 0) ++lookatValue[1];   //y
213                     else
214                         ++lightPos[1];
215                     break;
216                 case "btnE":
217                     if (obj == 0) --lookatValue[1];
218                     else
219                         --lightPos[1];
220                     break;
221                 case "btnW":
222                     if (obj == 0) --lookatValue[2];   //z
223                     else
224                        --lightPos[2];
225                     break;
226                 case "btnS":
227                     if (obj == 0)  ++lookatValue[2];
228                     else
229                         ++lightPos[2];
230                     break;
231                 case "btnA":
232                     if (obj == 0) --lookatValue[0];  //X
233                     else
234                        --lightPos[0];
235                     break;
236                 case "btnD":
237                     if (obj == 0)  ++lookatValue[0];
238                     else
239                         ++lightPos[0];
240                     break;
241             }
242         }
243
244         private void rbPerspective_CheckedChanged(object sender, EventArgs e)
245         {
246             switch (((RadioButton)sender).Name)
247             {
248                 case "rbPerspective":
249                     isPerspective = !isPerspective;
250                     isFrontView = false;
251                     isTopView = false;
252                     isLeftView = false;
253                     break;
254                 case "rbLeft":
255                      isLeftView = !isLeftView;
256                     isFrontView = false;
257                     isPerspective = false;
258                     isTopView = false;
259                     break;
260                 case "rbFront":
261                      isFrontView = !isFrontView;
262                     isTopView = false;
263                     isPerspective = false;
264                     isLeftView = false;
265                     break;
266                 case "rbTop":
267                      isTopView = !isTopView;
268                     isPerspective = false;
269                     isLeftView = false;
270                     isFrontView = false;
271                     break;
272                 default:
273                     return;
274             }
275             setViewDefaultValue();
276             openGLControl_Resized(null, null);
277         }
278
279         private void cbxRotate_CheckedChanged(object sender, EventArgs e)
280         {
281             var cbx=((CheckBox)sender);
282             switch (cbx.Name)
283             {
284                 case "cbxRotate":
285                     isRotate = cbx.Checked;
286                     break;
287                 case "cbxLines":
288                     isLines = cbx.Checked;
289                     break;
290                 case "cbxLightOff":
291                     if (!cbx.Checked)
292                         this.openGLControl.OpenGL.Enable(OpenGL.GL_LIGHT0);
293                     else
294                         this.openGLControl.OpenGL.Disable(OpenGL.GL_LIGHT0);
295                     break;
296             }
297         }
298
299         private void SharpGLForm_Load(object sender, EventArgs e)
300         {
301             this.cbxLightType.SelectedIndex = 0;
302             updateLabInfo();
303         }
304
305         private void updateLabInfo()
306         {
307             tbLightPos.Text = string.Format("{0},{1},{2},{3}", lightPos[0], lightPos[1], lightPos[2], lightPos[3]);
308             tbLookAt.Text = string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8}", lookatValue[0], lookatValue[1], lookatValue[2],
309                 lookatValue[3], lookatValue[4], lookatValue[5], lookatValue[6], lookatValue[7], lookatValue[8]);
310         }
311
312         private void rbWhite_CheckedChanged(object sender, EventArgs e)
313         {
314             var rad = ((RadioButton)sender);
315             var lightType = this.cbxLightType.SelectedIndex;
316             if (rad.Checked)
317             {
318                 switch (rad.Name)
319                 {
320                     case "rbWhite":
321                         lightColor[lightType][0] = 1f;
322                         lightColor[lightType][1] = 1f;
323                         lightColor[lightType][2] = 1f;
324                         lightColor[lightType][3] = 1f;
325                         break;
326                     case "rbRed":
327                         lightColor[lightType][0] = 1f;
328                         lightColor[lightType][1] = 0f;
329                         lightColor[lightType][2] = 0f;
330                         lightColor[lightType][3] = 1f;
331                         break;
332                     case "rbGreen":
333                         lightColor[lightType][0] = 0f;
334                         lightColor[lightType][1] = 1f;
335                         lightColor[lightType][2] = 0f;
336                         lightColor[lightType][3] = 1f;
337                         break;
338                     case "rbBlue":
339                         lightColor[lightType][0] = 0f;
340                         lightColor[lightType][1] = 0f;
341                         lightColor[lightType][2] = 1f;
342                         lightColor[lightType][3] = 1f;
343                         break;
344                 }
345                 setLightColor(openGLControl.OpenGL);
346             }
347         }
348
349         private void cbxLightType_SelectedIndexChanged(object sender, EventArgs e)
350         {
351             var lightType = this.cbxLightType.SelectedIndex;
352             if (lightType >= 0)
353                 judgeColor(lightColor[lightType]);
354         }
355
356         private void judgeColor(float[] color)
357         {
358             if (color[0] == 1f && color[1] == 1f && color[2] == 1f && color[3] == 1f)
359                 rbWhite.Checked = true;
360             else if (color[0] == 1f && color[1] == 0f && color[2] == 0f && color[3] == 1f)
361                 rbRed.Checked = true;
362             else if (color[0] == 0f && color[1] == 1f && color[2] == 0f && color[3] == 1f)
363                 rbGreen.Checked = true;
364             else if (color[0] == 0f && color[1] == 0f && color[2] == 1f && color[3] == 1f)
365                 rbBlue.Checked = true;
366         }
367
368         private void btnQ_Click(object sender, EventArgs e)
369         {
370             moveObject(radioButton1.Checked ? 0 : 1,((Button)sender).Name);
371             openGLControl_Resized(null, null);
372             openGLControl.OpenGL.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, lightPos);
373         }
374
375         private void setViewDefaultValue()
376         {
377             if (isPerspective)
378             {
379                 lookatValue = (double[])viewDefaultPos[0].Clone();
380             }
381             else if (isFrontView)
382             {
383                 lookatValue = (double[])viewDefaultPos[1].Clone();
384             }
385             else if (isLeftView)
386             {
387                 lookatValue = (double[])viewDefaultPos[2].Clone();
388             }
389             else if (isTopView)
390             {
391                 lookatValue = (double[])viewDefaultPos[3].Clone();
392             }
393         }
394
395         private void btnDefaultPOS_Click(object sender, EventArgs e)
396         {
397             if (radioButton1.Checked)
398             {
399                 setViewDefaultValue();
400             }
401             else
402             {
403                 lightPos = new float[] { -1, -3, 1, 1 };
404                 openGLControl.OpenGL.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, lightPos);
405             }
406             openGLControl_Resized(null, null);
407         }
408
409         private void openGLControl_KeyDown(object sender, KeyEventArgs e)
410         {
411             string name = string.Empty;
412             switch (e.KeyCode)
413             {
414                 case Keys.W:
415                     name = "btnW";
416                     break;
417                 case Keys.A:
418                     name = "btnA";
419                     break;
420                 case Keys.S:
421                     name = "btnS";
422                     break;
423                 case Keys.D:
424                     name = "btnD";
425                     break;
426                 case Keys.Q:
427                     name = "btnQ";
428                     break;
429                 case Keys.E:
430                     name = "btnE";
431                     break;
432             }
433             moveObject(radioButton1.Checked ? 0 : 1, name);
434             openGLControl_Resized(null, null);
435         }
436
437         private void btnSetPos_Click(object sender, EventArgs e)
438         {
439             if (radioButton1.Checked)
440             {
441                 double[] ary = tbLookAt.Text.Split(‘,‘).Select(s => Convert.ToDouble(s)).ToArray();
442                 lookatValue = ary;
443                 openGLControl_Resized(null, null);
444             }
445             else
446             {
447                 float[] ary = tbLightPos.Text.Split(‘,‘).Select(s => Convert.ToSingle(s)).ToArray();
448                 lightPos = ary;
449                 openGLControl.OpenGL.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, ary);
450             }
451
452         }
453
454
455     }
456 }

有关灯光的代码如下粗体显示部分:

 1   private void setLightColor(OpenGL gl)
 2         {
 3             gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_AMBIENT, lightColor[0]);
 4             gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_DIFFUSE, lightColor[1]);
 5             gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_SPECULAR, lightColor[2]);
 6         }
 7
 8         private void openGLControl_OpenGLInitialized(object sender, EventArgs e)
 9         {
10             OpenGL gl = openGLControl.OpenGL;
11
12             //四个视图的缺省位置
13             viewDefaultPos.Add(new double[] { 1, 1, 2, 0, 0, 0, 0, 1, 0 });     //透视
14             viewDefaultPos.Add(new double[] { 0, 0, 2, 0, 0, 0, 0, 1, 0 });     //前视
15             viewDefaultPos.Add(new double[] { 5, 0, 0, 0, 0, 0, 0, 1, 0 });     //左视
16             viewDefaultPos.Add(new double[] { 0, 13, 0, -1, 0, 0, 0, 1, 0 });   //顶视
17             lookatValue =(double[])viewDefaultPos[0].Clone();
18
19             lightColor.Add(new float[] { 1f, 1f, 1f, 1f });  //环境光(ambient light)
20             lightColor.Add(new float[] { 1f, 1f, 1f, 1f });  //漫射光(diffuse light)
21             lightColor.Add(new float[] { 1f, 1f, 1f, 1f });  //镜面反射光(specular light)
22
23             setLightColor(gl);
24             gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, lightPos);
25
26             gl.Enable(OpenGL.GL_LIGHTING);
27             gl.Enable(OpenGL.GL_LIGHT0);
28
29             gl.ClearColor(0, 0, 0, 0);
30         }

第3,4,5行是创建灯光三个部分 环境光,漫射光,镜面反射光。

第24行是设定灯光的位置。

第26,27是让灯光开,有效。

灯光代码确实比较简单,这段代码其它部分没什么好说的,笔者按界面功能直述其意,朋友们应该很容易懂。

唯一要关注下的是:视图和灯光的参数修改是如何实时生效的。

本节源代码下载

原创文章,出自"博客园, 猪悟能‘S博客" : http://www.cnblogs.com/hackpig/

时间: 2024-10-14 04:57:39

SharpGL学习笔记(十一) 光源创建的综合例子:光源参数可调节的测试场景的相关文章

《Hibernate学习笔记十一》:树状结构设计

<Hibernate学习笔记十一>:树状结构设计 这是马士兵老师讲解Hibernate的一个作业题,树状结构设计,这是一个比较典型的例子,因此有必要写篇博文记录下. 树状结构的设计,它是在同一个类中使用了多对一(ManyToOne)和一对多(OneToMany). 在完成这个题目我们应该按照如下的步骤进行: 1.先思考数据库的模型应该是什么样的?? 数据库中的模型应该如下:即存在id p_id 2.思考面向对象的模型,及如何来进行映射??? 根据数据库中表的特点,对象应该有id name;由于

初探swift语言的学习笔记十一(performSelector)

作者:fengsh998 原文地址:http://blog.csdn.net/fengsh998/article/details/35842441 转载请注明出处 如果觉得文章对你有所帮助,请通过留言或关注微信公众帐号fengsh998来支持我,谢谢! 在OC中使用好好的performSelector,但不知为什么在swift有意的被拿掉了.更有甚者连IMP, objc_msgSend也不能用了.虽然想不通为什么,但应该有他的道理.就不纠结了. 大家可能在OC中使用得更多的就是延时处理,及后台处

第十七篇:实例分析(4)--初探WDDM驱动学习笔记(十一)

感觉有必要把 KMDDOD_INITIALIZATION_DATA 中的这些函数指针的意思解释一下, 以便进一步的深入代码. DxgkDdiAddDevice 前面已经说过, 这个函数的主要内容是,将BASIC_DISPLAY_DRIVER实例指针存在context中, 以便后期使用, 支持多实例. DxgkDdiStartDevice 取得设备信息, 往注册表中加入内容, 从POST设备中获取FRAME BUFFER以及相关信息(DxgkCbAcquirePostDisplayOwnershi

SharpGL学习笔记(七) OpenGL的变换总结

笔者接触OpenGL最大的困难是: 经常调试一份代码时, 屏幕漆黑一片, 也不知道结果对不对,不知道如何是好! 这其实就是关于OpenGL"变换"的基础概念没有掌握好, 以至于对"将三维体正确的显示在屏幕上指定位置"这样的操作都无法完成. OpenGL变换包括计算机图形学中最基本的三维变换,即几何变换.投影变换.裁剪变换.视口变换,以及针对OpenGL的特殊变换概念理解和用法,如相机模拟.矩阵堆栈等,这些基础是开始真正走进三维世界无法绕过的基础. 所以笔者在前面花了

ObjectARX 学习笔记007:创建模态对话框的一般步骤

1.新建一个工程,注意将"使用MFC"选项勾上. 2.使用[insert/Resouce]菜单项插入一个对话框. 3.此时会弹出一个窗体,直接按Enter键可以调出[属性]面板.设置窗体的ID和窗体的Caption. 4.可以点击[属性]面板左上角的图钉图标将其常显. 5.向窗体中插入控件,依次设置其ID与Caption. 6.按Ctrl+W为对话框资源创建一个类.此时系统会在工程中添加一个.cpp文件和一个对应的.h文件. 7.注册一个新命令,用于显示新的对话框. 8.在xxxCom

sqlite学习笔记2:创建数据库

在上一次笔记中最后生成了一个sqlite可执行文件,cd到sqlite所在的目录下面执行: sqlite3 MyDataBase.db 就会创建了一个名叫MyDataBase.db的数据库,在当前路径下面就会生成一个叫MyDataBase.db的文件 #切记不是先运行sqlite3,然后再上述命令,而是在终端直接输入上述命令,否则会报错:Error: near "sqlite3": syntax error 然后运行命令: .databases 可以查看刚刚创建的数据库,退出数据库命令

Linux System Programming 学习笔记(十一) 时间

1. 内核提供三种不同的方式来记录时间: Wall time (or real time):actual time and date in the real world Process time:the time that a process spends executing on a processor 包括用户时间user time 和 系统时间system time Monotonic time:use the system's uptime (time since boot) for t

Python学习笔记__4.5章 偏函数(绑定函数参数)

# 这是学习廖雪峰老师python教程的学习笔记 1.概览 偏函数(Partial function)是functools模块的一个功能 functools.partial的作用就是,在一个已存在的函数基础上.把它的某些参数给固定住(也就是设置默认值),然后返回一个新的函数,调用这个新函数会更简单. 1.1.functools. partial 应用 已知: int 函数可以将 '123' --> 123. int 的 base 参数可以做 N 进制的转换 >>> int('123

ZMAN的学习笔记之Python篇:函数可变长参数

ZMAN的学习笔记之Python篇: 1.装饰器 2.函数“可变长参数” 这次来聊聊Python中函数的“可变长参数”,在实际中经常会用到哦~  一.什么是“可变长参数” “可变长参数”就是向一个函数传入不定个数的参数.比如我写一个函数:传入一个学生参加各科目考试的成绩,求平均分,如两个学生分别传入(92, 91, 88)和(88, 95),因为每个学生参加的考试个数不同,因此传入的参数个数也就不同了,遇到这种情况,我们在定义函数的时候,可以使用“可变长参数”. 二.在定义函数时使用“可变长参数