类的定义:类是有一些系列有共同特征和行为事物的抽象概念的总和。
类的属性:
class CocaCola:
formula = ['caffeine','sugar','water','soda']
其中fornula就称之为类的属性
类的实例化:
coke_for_me = CocaCola()
coke_for_you = CocaCola()
在左边创建一个变量,右边写上类的名称,这样看起来很像是赋值的行为,我们称之为类的实例化。而被实例化后的对象,我们称之实例(instance)
类属性引用:
在类的名字后面输入‘.’,IDE就会自动联想出我们之前在定义类的时候写在里面的属性,而这就是类属性的引用(attribute)
类的属性会被所有类的实例共享,所以当你在类的实例后面再加上‘.’,索引的属性是完全一样的。
print(CocaCola.formula)
print(coke_for_me.formula)
print(coke_for_you.formula)
print(CocaCola.formula)
print(coke_for_me.formula)
print(coke_for_you.formula)
#输出结果:
>>> ['caffeine','sugar','water','soda']
>>> ['caffeine','sugar','water','soda']
>>> ['caffeine','sugar','water','soda']
#类属性与正常的变量并无区别:
for element in coke_for_me.formula:
print(element)
#输出结果:
>>> caffeine
>>> sugar
>>> water
>>> soda
实例属性:
class CocaCola:
formula = ['caffeine','sugar','water','soda']
coke_for_China = CocaCola()
coke_for_China.local_logo = '可口可乐' #创建实力属性
print(coke_for_China.local_logo) #打印实力属性引用结果
在创建类之后,通过Object.new_attr 的形式进行一个赋值,于是我们就得到了一个新的实例的变量,我们称之为实例属性(Instance Atrribute)
实例方法:
方法就是函数,并可以供实例调用,我们称之为实例方法(Instance Method)
class CocaCola:
formula = ['caffeine','sugar','water','soda']
def drink(self):
print('Energy!')
coke = CocaCola()
coke.drink()
#输出结果:
>>> Energy!
self:该参数其实就是被创建的实例本身。被实例化的对象会被编译器默默地传入后面方法的括号里,作为第一个参数,下面这两种方法是一样的,但更多的写成前面的形式。其中self这个参数名称是可以随意修改名称的(编译器不会报错),但是约定俗成统一用self。
coke = CocaCola
coke.drink() == CocaCola.drink(coke) #左右两边的写法完全一致
小例子:
class CocaCola:
formula = ['caffeine','sugar','water','soda']
def drink(self,how_much):
if how_much == 'a sip':
print('Cool~')
elif how_much == 'whole bottle'
print('Headache!')
ice_coke = CocaCola()
ice_coke.drink('a sip')
#输出结果:
>>> Cool~
类中的__init__()方法:
__init__是initialize(初始化)的缩写,意味着在创建实例的时候不用去引用该函数,其中的命令也会先被自动执行。类似于JAVA的构造函数。
例1:
class CocaCola():
formula = ['caffeine','sugar','water','soda']
def __init__(self):
self.local_logo = '可口可乐'
def drink(self): # HERE!
print('Energy!')
coke = CocaCola()
print(coke.local_logo)
#输出结果:
可口可乐
例2:
class CocaCola:
formula = ['caffeine','sugar','water','soda']
def __init__(self):
for element in self.formula:
print('Coke has {}!'.format(element))
def drink(self):
print('Energy!')
coke = CocaCola()
#输出结果:
Coke has caffeine!
Coke has sugar!
Coke has water!
Coke has soda!
除了必写的self参数之外,__init__()同样可以有自己的参数,同时不需要这样Obj__init__()的方式来调用(因为是自动执行)而是在实例化的时候往类的后面的括号放进参数,相应的所有参数都会传递到这个特殊的__init__()方法中,和函数的参数用法完全相同。
class CocaCola:
formula = ['caffeine','sugar','water','soda']
def __init__(self,logo_name):
self.local_logo = logo_name
def drink(self):
print('Energy!')
coke = CocaCola('可口可乐')
coke.local_logo
#输出结果:
可口可乐
类的继承(Inheritance):
一个类可以作为子类继承其他类的类属性,被继承的类称为父类。
例子:
#父类:
class CocaCola:
calories = 140
sodium = 45
total_carb = 39
caffeine = 34
ingredients = [
'High Fructose Corn Syrup',
'Carbonated Water',
'Phosphoric Acid',
'Natural Flavors',
'Caramel Color',
'Caffeine'
]
def __init__(self,logo_name):
self.local_logo = logo_name
def drink(self):
print('You got {} cal energy!'.format(self.calories))
#子类:
class CaffeineFree(CocaCola):
caffeine = 0
ingredients = [ #覆盖
'High Fructose Corn Syrup',
'Carbonated Water',
'Phosphoric Acid',
'Natural Flavors',
'Caramel Color',
]
coke_a = CaffeineFree('Cocacola-FREE')
coke_a.drink()
类中的变量和方法可以完全被子类继承,但如需有特殊的改动也可以进行覆盖(Override)
类的实践:
制作一个填充用户假数据的小工具,设计思路如下:
- 父类:FakeUser
- 功能:
- 1.随机姓名
- ①单子名
- ②双字名
- ③有名字就可以
- 2.随机性别
- 子类:SnsUser
- 功能:
- 1.随机数量的跟随者
- ①few
- ②a lot
ln_path = 'C:/Users/ASUS/Desktop/last_name.txt'
fn_path = 'C:/Users/ASUS/Desktop/first_name.txt'
ln = []
fn1 = [] #单字名
fn2 = [] #双字名
with open(ln_path,'r') as f:
for line in f.readlines():
ln.append(line.split('\n')[0])
ln_tup = tuple(ln) #转换成元组存储,更节省空间,并且这些是常量。
print(ln_tup)
print('='*60) #分割线
with open(fn_path,'r') as f:
for line in f.readlines():
if len(line.split('\n')[0]) == 1:
fn1.append(line.split('\n')[0])
else:
fn2.append(line.split('\n')[0])
fn1_tup = tuple(fn1)
fn2_tup = tuple(fn2)
print(fn1_tup)
print(fn2_tup)
import random
class FakeUser:
def fake_name(self,one_word=False,two_word=False):
if one_word:
full_name = random.choice(ln) + random.choice(fn1)
elif two_word:
full_name = random.choice(ln) + random.choice(fn2)
else:
full_name = random.choice(ln) + random.choice(fn1 + fn2)
print(full_name)
def fake_gender(self):
gender = random.choice(['男','女','未知'])
print(gender)
class SnsUser(FakeUser):
def get_followers(self,few = True,a_lot = False):
if few:
followers = random.randrange(1,50)
elif a_lot:
followers = random.randrange(200,10000)
print(followers)
user_a = FakeUser()
user_b = SnsUser()
user_a.fake_name()
user_b.get_followers(few=True)
#输出结果:
('李', '王', '张', '刘')
============================================================
('娉', '王', '莱')
('广利', '志明', '二狗', '正顺', '书铎')
张书铎
11
改进:
我们的目的是批量制造假的填充数据,但是目前只能是手工添加,因此要在原有代码上做一些调整。把所有的print替换成yield并在上方加上一层循环。这里用到了一个新的概念:生成器(generator)。简单的来说,在函数中我们只要在任一一种循环(loop)中使用yield返回结果,就可以得到类似于range函数的效果。
Python—yield(剖析)
ln_path = 'C:/Users/ASUS/Desktop/last_name.txt'
fn_path = 'C:/Users/ASUS/Desktop/first_name.txt'
ln = []
fn1 = [] #单字名
fn2 = [] #双字名
with open(ln_path,'r') as f:
for line in f.readlines():
ln.append(line.split('\n')[0])
ln_tup = tuple(ln) #转换成元组存储,更节省空间,并且这些是常量。
print(ln_tup)
print('='*60) #分割线
with open(fn_path,'r') as f:
for line in f.readlines():
if len(line.split('\n')[0]) == 1:
fn1.append(line.split('\n')[0])
else:
fn2.append(line.split('\n')[0])
fn1_tup = tuple(fn1)
fn2_tup = tuple(fn2)
print(fn1_tup)
print(fn2_tup)
import random
class FakeUser:
def fake_name(self,amount = 1,one_word=False,two_word=False):
n = 0
while n <= amount:
if one_word:
full_name = random.choice(ln) + random.choice(fn1)
elif two_word:
full_name = random.choice(ln) + random.choice(fn2)
else:
full_name = random.choice(ln) + random.choice(fn1 + fn2)
yield full_name
n += 1
def fake_gender(self,amount = 1):
n = 0
while n <= amount:
gender = random.choice(['男','女','未知'])
yield gender
n+=1
class SnsUser(FakeUser):
def get_followers(self,amount = 1,few = True,a_lot = False):
n = 0
while n <= amount:
if few:
followers = random.randrange(1,50)
elif a_lot:
followers = random.randrange(200,10000)
yield followers
n += 1
user_a = FakeUser()
user_b = SnsUser()
for name in user_a.fake_name(30):
print(name)
for gender in user_b.fake_gender(30):
print(gender)
#输出结果:
刘王
李广利
李二狗
张二狗
李莱
刘娉
李书铎
刘正顺
李娉
李王
刘王
刘志明
张王
张书铎
李王
张二狗
女
女
男
男
女
男
男
未知
男
未知
男
未知
未知
男
未知
男
24
43
23
20
19
9
38
38
38
46
11
37
31
33
10
4