class Person (object):
# 类属性name
name = 'djk'
# 类函数dump
def dump (self):
# 如果不加self,则获取不到name
print (f'{self.name} is dumping')
# 实例化一个类
p = Person ()
print (p.name)
p.dump()
>>djk
>>djk is dumping
# self是类函数中的必传参数,且必须放在第一个参数位置
# self 是一个对象,代表实例化的变量自身
# self 可以直接通过点来定义一个类变量
# self中的变量与含有self参数的函数可以再类中的任何一个函数内随意调用
# 非函数中定义的变量在定义时可以不用self
class Person (object):
name = None
age = None
def run (self):
print (f'{self.name} is running')
def jump (self):
print (f'{self.name} is jumping')
def work (self):
self.run()
self.jump()
def sleep ():
print ('sleep')
p = Person ()
p.jump ()
p.name = 'djk'
p.jump ()
# 属性修改只针对实例化的对象,p和p2属于两个不同的实例化
p2 = Person ()
p2.jump ()
# 添加一个属性
p2.top = 199
print (p2.top)
# 和p是不通用的
# print (p.top)
#>>'Person' object has no attribute 'top'
p.work()
# 类中的函数如果不加self,则无法进行调用
# p.sleep()
# >>sleep() takes 0 positional arguments but 1 was given
class DemoClass: # 定义一个类
def __init__(self, name):
print(name)
dc1 = DemoClass("小明")
dc2 = DemoClass("小吴")
>>小明
>>小吴
# 私有函数与私有变量:无法被实例化后的对象调用的类中的函数与变量
# 类内部可以调用私有函数与变量
# 只希望类内部业务调用使用,不希望被使用者调用
# 在变量或者函数前加两个下横线__,变量或函数后无需添加
class Cat (object):
# 私有属性
__cat_type = 'cat'
def __init__(self, name, sex):
self.name = name
self.__sex = sex
def run (self):
# 调用私有函数
result = self.__run()
print (result)
# 私有函数
def __run (self):
return f'{self.name} run {self.__sex}'
def dump (self):
result = self.__dump ()
print (result)
def __dump (self):
return f'{self.__cat_type}{self.name} dump {self.__sex}'
cat = Cat ('sss', 'male')
cat.run()
cat.dump()
>>sss run male
>>catsss dump male
一句话说就是,在函数中再嵌套一个函数,并且引用外部函数的变量,这就是一个闭包了。
def outer(x):
def inner(y):
return x + y
return inner
print(outer(6)(5))
-----------------------------
>>>11
如代码所示,在outer函数内,又定义了一个inner函数,并且inner函数又引用了外部函数outer的变量x,这就是一个闭包了。在输出时,outer(6)(5),第一个括号传进去的值返回inner函数,其实就是返回6 + y,所以再传第二个参数进去,就可以得到返回值,6 + 5。
也是一种函数
可以接收函数作为参数
可以返回参数
接受一个函数,内部对其处理,然后返回一个新函数,动态增强函数功能
将C函数在a函数中执行,在a函数中可以选择执行或不执行c函数,也可以对c函数的结果进行二次加工处理
装饰器就是一个闭包,装饰器是闭包的一种应用。什么是装饰器呢,简言之,python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。使用时,再需要的函数前加上@demo即可。
def debug(func):
def wrapper():
print("[DEBUG]: enter {}()".format(func.__name__))
return func()
return wrapper
@debug
def hello():
print("hello")
hello()
-----------------------------
>>>[DEBUG]: enter hello()
>>>hello
def logging(level):
def outwrapper(func):
#传入的是外围函数对应的参数
def wrapper(*args, **kwargs):
print("[{0}]: enter {1}()".format(level, func.__name__))
return func(*args, **kwargs)
return wrapper
return outwrapper
@logging(level="INFO")
def hello(a, b, c):
print(a, b, c)
hello("hello,","good","morning")
-----------------------------
>>>[INFO]: enter hello()
>>>hello, good morning
如上,装饰器中可以传入参数,先形成一个完整的装饰器,然后再来装饰函数,当然函数如果需要传入参数也是可以的,用不定长参数符号就可以接收,例子中传入了三个参数。
def check_str (func):
def inner (*args, **kwargs):
result = func (*args, **kwargs)
if result == 'ok':
print ('is ok')
else:
print ('not ok')
return inneris ok
@check_str
def test (data):
return data
test ('ok')
>>is ok
# classmethod:将类函数可以不经过实例化而被直接调用
'''
@classmethod
def func (cls, ...):
do
参数介绍:cls替代普通类函数中的self变为cls,代表当前操作的是类
'''
如果不进行实例化,直接用类调用类函数是不可以的,如下:
class Test (object):
def __init__ (self, a):
self.a = a
def run (self):
print ('run')
Test.run()
>>TypeError: run() missing 1 required positional argument: 'self'
这时候classmethod派上用场
class Test (object):
def __init__ (self, a):
self.a = a
def run (self):
print ('run')
@classmethod
def dump (cls):
print ('dump')
Test.dump()
>>dump
不能在classmethod的类函数装饰器中调用一个self函数
class Test (object):
def __init__ (self, a):
self.a = a
def run (self):
print ('run')
@classmethod
def dump (cls):
print ('dump')
cls.run()
Test.dump()
>>run() missing 1 required positional argument: 'self'
可以在普通的self函数中调用classmethod的装饰器函数
class Test (object):
def __init__ (self, a):
self.a = a
def run (self):
print ('run')
self.dump()
@classmethod
def dump (cls):
print ('dump')
t = Test ('a')
t.run()
>>run
>>dump
# staticmethod:将类函数可以不经过实例化而被直接调用
#被该装饰器调用的函数不许传递self或cls参数,且无法在该函数内调用其他类函数或类变量
'''
@staticmethod
def func (...):
do
'''
class Test (object):
def __init__ (self, a):
self.a = a
def run (self):
print ('run')
self.dump()
@classmethod
def dump (cls):
print ('dump')
@staticmethod
def sleep ():
print ('sleep')
Test.sleep()
>>sleep
可以在普通的self函数中调用staticmethod的装饰器函数
class Test (object):
def __init__ (self, a):
self.a = a
def run (self):
print ('run')
self.dump()
self.sleep()
@classmethod
def dump (cls):
print ('dump')
@staticmethod
def sleep ():
print ('sleep')
t = Test ('a')
t.run()
>>run
>>dump
>>sleep
# property:将类函数的执行免去括弧,类似于调用属性
'''
@property
def func (self):
do
'''
class Test1 (object):
def __init__ (self, name):
self.__name = name
@property
def name (self):
return self.__name
t1 = Test1 (name = 'djk')
print (t1.name)
如果要修改property的返回值,使用@func_name__.setter,他是一个装饰器,并且在定义一个函数和原函数名称相同
class Test1 (object):
def __init__ (self, name):
self.__name = name
@property
def name (self):
return self.__name
@name.setter
def name (self, value):
self.__name = value
t1 = Test1 (name = 'djk')
print (t1.name)
t1.name = 'ddd'
print (t1.name)
>>djk
>>ddd
class Parent (object):
def __init__ (self, name, sex):
self.name = name
self.sex = sex
def talk (self):
return f'{self.name} are walking'
def is_sex (self):
if self.sex == 'boy':
return f'{self.name} is a boy'
else:
return f'{self.name} is a girl'
class ChildOne (Parent):
def play_football (self):
return f'{self.name} is playing football'
class ChildTwo (Parent):
def play_pingpong (self):
return f'{self.name} is playing pingong'
c_one = ChildOne ('djk', 'boy')
result = c_one.play_football()
print (result)
result = c_one.talk()
print (result)
c_two = ChildTwo ('ymj', 'girl')
result = c_two.play_pingpong()
print (result)
result = c_two.talk()
print (result)
p = Parent ('father', 'boy')
result = p.is_sex ()
print (result)
'''
result = p.play_football()
print (result)
这是错误的,父类不能调用子类自有的方法
'''
python子类继承父类的方法而使用的关键字,当子类继承父类后,就可以使用父类的方法
class Parent (object):
def __init__ (self):
print ('hello i am parent')
class Child (Parent):
def __init__(self):
print ('hello i am child')
super (Child,self).__init__()
c = Child ()
>>hello i am child
>>hello i am parent
# 传值的用法
class Parent (object):
def __init__ (self, p):
print ('hello i am parent %s' %p)
class Child (Parent):
def __init__(self, c, p):
print ('hello i am child %s' % c)
super (Child,self).__init__(p)
c = Child ('child', 'parent')
>>hello i am child child
>>hello i am parent parent
可以继承多个父类
class Tool (object):
def work (self):
return 'tool work'
def car (self):
return 'car will run'
class Food (object):
def work (self):
return 'food work'
def cake (self):
return 'i like cake'
class Person (Tool, Food):
pass
p = Person()
print (p.car())
print (p.cake())
print (p.work()) #最左边的类先被继承
print (Person.__mro__)
同一个功能的多状态变化
class Parent (object):
def talk (self):
print ('father talk')
class brother (Parent):
def run (self):
print ('bro run')
def talk (self):
print ('bro talk')
bro = brother ()
bro.run ()
bro.talk()
father = Parent()
father.talk()
'''
如果定义了该函数,当print当前实例化对象的时候,会返回该函数的return信息
def __str__ (self):
return str_type
'''
class Test (object):
def __str__ (self):
return "类的描述"
t = Test()
print (t)
>>类的描述
'''
当调用的属性或者方法不存在时,会返回该方法定义的信息
def __getattr__(self, key):
print (something)
key:调用任意不存在的属性名
'''
class Test (object):
def __getattr__ (self, key):
return "这个key:{}不存在".format (key)
t = Test()
print (t.a)
>>这个key:a不存在
'''
拦截当前类中不存在的属性和值
def __setattr__(self,key,value):
self.__dict__[key] = value
key:当前的属性名
value:当前参数对应的值
'''
class Test (object):
def __setattr__ (self, key, value):
if key not in self.__dict__:
self.__dict__[key] = value
t = Test()
t.name = 'djk'
print (t.name)
>>djk
'''
本质是将一个类变成一个函数
def __call__ (self, *args, **kwargs):
print ('call will start')
'''
class Test (object):
def __call__ (self, a):
print ('call func will start')
print (a)
t = Test()
t ('hello')
>>call func will start
>>hello