昨天在写UML类图的时候看到了这样一段代码
#问女性的姓名、工作是没有问题的,但是问女性的年龄、体重是不礼貌的,所以我们把女性年龄定义为私有属性
#定义显示女性的姓名、工作为公有方法,显示女性年龄、体重为私有方法
#类的定义部分
class Woman():
name = "Juckes" #类的公有属性
job = "Teacher"
__ages = 30 #类的私有属性
__weight = 60
def disp_nj_info(self): #类的(公有)方法
print("Name:{}, Job:{}".format(self.name,self.job)) #类的内部调用公有属性
def __disp_aw_info(self): #类的私有方法
print("Age:{}, Weight:{}".format(self.__ages, self.__weight)) #类的内部调用私有属性
def dis_all_info(self):
self.disp_nj_info() #类的内部调用公有方法
self.__disp_aw_info() #类的内部调用私有方法
原链接
觉得很有意思,决定深挖一下。
1. 创建一个普通的类
class Woman():
pass
a = Woman()
a就是一个普通的女人。这样的代码不难理解,但也没什么用。
2. 创建有属性、方法的类
class Woman():
bottom_salary = 10000
def salary(self, years):
self.salary = years * 10
在这一次的类中,我们定义了属性bottom_salary和方法salary
a = Woman()创建了一个Woman类,由于所有的Woman类,属性bottom_salary都是10000
所以,只要创建这个类,对象a就有了属性bottom_salary而且属性值为10000
a.salary(10)调用了salary方法,该方法在定义之处就要求,输入两个参量
其中self由Woman类的对象的名字代替,无需再输入,但是years需要再输入。
所以本次调用相当于a.salary(a, 10)
调用结果是:a.salary = 10 * 10
此时,a的属性salary可以通过调用a.salary得到(不是a.salary())
3. 使用__init__()创建方法
很多python教程里都会使用__init__()创建方法,现在我们来实现一下。
class Woman():
def __init__(self, years):
self.salary = years * 10
跟上面代码不同的是,建立Woman类a的时候报错了,原因是__init__()方法缺少了一个参数。
所以说,与上面定义的salary方法不同的是, _ init _()方法在对象创建之初就自动调用。
两者对比如下:
4. 一些奇怪的角度
看完以上的这些,你已经掌握了Python类的基础用法。
但是,想要彻底掌握一个点,需要不断的去破坏现有的知识结构。
比如这段代码:
class Woman():
bottom_salary = 10000
def salary(self, years):
salary = years * 10
跟上面的相比,我把salary前面的self去掉了。
因为,bottom_salary前面没加self,bottom_salary是Woman的一个属性,salary不加self也会是属性吗?
我们用内置的dir()查看一下:
是有的,但是能调出来吗?
不可以,调是可以调,但不是我们想要的
以上显示,a.salary是一个方法对象。
换一个名字:
查看属性:
没有s属性。
通过以上实验可知,在def外,属性可以直接定义,def内,属性必须要self.xxx这样子定义。可以借助uml图方便理解。
第二个点:
我能在薪资方法里调用底薪属性吗?
显然是不可以的。
有的时候构造类的方法,很容易让人想到普普通通构造一个函数。
都有传参,都用def,但二者是不同的。
普通函数可以调def外的全局变量,方法构造不可以。
上图是构造普通函数,函数外定义的全局变量可以使用。
那怎么才能在类的内部算上底薪呢?
class Woman():
def __init__(self, years):
minimum_salary = 10000
self.salary = years * 10 + minimum_salary
a = Woman(10)
在定义方法的时候顺便底薪即可。
第三个点:
同一类,不同方法直接可以相互调用吗?
如果不是构造类,只是构造两个普普通通的函数,显然答案是可以的。
在构造类的时候可以用这样的思路吗?
可以的