魔方方法总是被双下划线包围,例如__init__。魔方方法是面向对象的python的一切。
魔方方法的“魔力”体现在他们总能够在适当的时候被自动调用。
class Rectangle:
def __init__(self,x,y):
self.x = x
self.y = y
def getPeri(self):
return (self.x+self.y) * 2
def getArea(self):
return self.x * self.y
rect = Rectangle(4,5)
print(rect.getPeri()) # 18
print(rect.getArea) # 20
class A(object):
def __init__(self,value):
print("into A__init__")
self.value = value
def __new__(cls,*args,**kwargs):
print("into A __new__")
print("cls")
return object.__new__(cls)
class B(A):
def __init__(self,value):
print("into B __init__")
self.value = value
def __new__(cls,*args,**kwargs):
print("into B __new__")
print(cls)
return super().__new__(cls,*args,**kwargs)
b = B(10)
# into B __new__
#
# into A __new__
#
# into B __init__
## 但是不知道怎么做;
class A(object):
def __init__(self,value):
print("into A __init__")
self.value = value
def __new__(cls,*args,**kwargs):
print("into A __new__")
print(cls)
return object.__new__(cls)
class B(A):
def __init__(self,value):
print("into B __init__")
self.value = value
def __new__(cls,*args,**kwargs):
print("into B __new__")
print(cls)
return super().__new__(A,*args,**kwargs) # 改动了cls变为A
b = B(10)
# into B __new__
#
# into A __new__
#
【例子】利用__new__实现单例模式
class Earth:
pass
a = Earth()
print(id(a)) # 260728291456
b = Earth(0
print(id(b)) # 260728291624
class Earth:
__instance = None # 定义一个类属性做判断
def __new__(cls):
if cls.__instance is None:
cls.__instance = object.__new__(cls)
return cls.__instance
else:
cls.__instance
a = Earth()
print(id(a)) # 512320401648
b = Earth()
print(id(b)) # 512320401648
class CapStr(str):
def __new__(cls,string):
string = string.upper()
return str.__new_(cls,string)
a = CapStr("i love lsgogroup")
print(a) # I LOVE LSOGROUP
Python 采用自动引用计数(ARC)方式来回收对象所占用的空间,当程序中有一个变量引用该 Python 对象时,Python 会自动保证该对象引用计数为 1;当程序中有两个变量引用该 Python 对象时,Python 会自动保证该对象引用计数为 2,依此类推,如果一个对象的引用计数变成了 0,则说明程序中不再有变量引用该对象,表明程序不再需要该对象,因此 Python 就会回收该对象。
大部分时候,Python 的 ARC 都能准确、高效地回收系统中的每个对象。但如果系统中出现循环引用的情况,比如对象 a 持有一个实例变量引用对象 b,而对象 b 又持有一个实例变量引用对象 a,此时两个对象的引用计数都是 1,而实际上程序已经不再有变量引用它们,系统应该回收它们,此时 Python 的垃圾回收器就可能没那么快,要等专门的循环垃圾回收器(Cyclic Garbage Collector)来检测并回收这种引用循环。
【例子】
class C(object):
def __init__(self):
print('into C __init__')
def __del__(self):
print("into C__del__")
c1 = C()
# into C __init__
c2 = c1
c3 = c2
del c3
del c2
del c1
# into C __del__
class Cat:
""" 定义一个猫类 """
def __init__(self,new_name,new_age):
""" 在创建完对象之后,会自动调用,它完成对象的初始化的功能"""
self.name = new_name
self.age = new_age
def __str__(self):
"""返回一个对象的描述信息"""
return "名字是:%s,年龄是:%d" %(self.name,self.age)
def __repr__(self):
"""返回一个对象的描述信息"""
return "Cat:(%s,%d)" %(self.name,self.age)
def eat(self):
print("%s在吃鱼..." % self.name)
def drink(self):
print("%s在喝可乐..." % self.name)
def introduce(slef):
print("名字是:%s,年龄是:%d " %(self.name,self.age))
# 创建了一个对象
tom = Cat("汤姆",30)
print(tom) # 名字是:汤姆,年龄是:30
print(str(tom)) # 名字是:汤姆,年龄是:30
print(repr(tom)) # Cat:(汤姆,30)
tom.eat() # 汤姆在吃鱼...
tom.introduce() # 名字是:汤姆,年龄是:30
str(self)的返回结果代码可读性强。即__str__ 的意义是得到便于人们阅读的信息,就像下面的 ‘2019-10-11’ 一样。
repr(self) 的返回结果应更准确。怎么说,repr 存在的目的在于调试,便于开发者使用。
【例子】
import datatime
today = datatime.date.today()
print(str(today)) # 2019-10-11
print(repr(today)) # datetime.date(2019,10,11)
print("%s " %today) # 2019-10-11
print("%r" %today) # datetime.date(2019,10,11)
类型工厂函数,指的是“不通过类而通过函数来创建对象”
【例子】
class C:
pass
print(type(len)) #
print(type(len)) #
print(type(dir)) #
print(type(int)) #
print(type(list)) #
print(type(tuple)) #
print(type(C)) #
print(int('123')) # 123
# 这个例子中list工厂函数把一个元组对象加工成了一个列表对象
print(list((1,2,3))) # [1,2,3]
class MyClass:
def __init__(self,height,weight):
self.height = height
self.weight = weight
# 两个对象的长相加,宽不变,返回一个新的类
def __add__(self,others):
return MyClass(self.height+others.height, self.weight-others.weight)
# 两个对象的宽相减,长不变.返回一个新的类
def __sub__(self,others):
return MyClass(self.height-others.height,self.weight-others.weight)
# 输出自己的参数
def intro(self):
print("Height: ", self.height,"Weight: ",self.weight)
def main():
a = MyClass(10,5)
a. intro
b = MyClass(20,10)
b.intro
c = b-a
c.intro()
d = a+b
d.intro()
if __name__ == "__main__":
main()
# 高为 10 重为 5
# 高为 20 重为 10
# 高为 10 重为 5
# 高为 30 重为 15
mul(self, other)定义乘法的行为:*
truediv(self, other)定义真除法的行为:/
floordiv(self, other)定义整数除法的行为://
mod(self, other) 定义取模算法的行为:%
divmod(self, other)定义当被 divmod() 调用时的行为
divmod(a, b)把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)。
【例子】
print(divmod(7,2)) # (3,1)
print(divmod(8,2)) # (4,0)
反运算魔方方法,与算术运算符保持一一对应,不同之处就是反运算的魔方方法多了一个"r"。
当文件做操作不支持相应的操作时被调用。
radd(self, other)定义加法的行为:+
rsub(self, other)定义减法的行为:-
rmul(self, other)定义乘法的行为:*
rtruediv(self, other)定义真除法的行为:/
rfloordiv(self, other)定义整数除法的行为://
rmod(self, other) 定义取模算法的行为:%
rdivmod(self, other)定义当被 divmod() 调用时的行为
rpow(self, other[, module])定义当被 power() 调用或 ** 运算时的行为
rlshift(self, other)定义按位左移位的行为:<<
rrshift(self, other)定义按位右移位的行为:>>
rand(self, other)定义按位与操作的行为:&
rxor(self, other)定义按位异或操作的行为:^
ror(self, other)定义按位或操作的行为:
a + b
这里的加数是a,被加数是b,因此是a主动,,反运算就是如果a对象的__add__()方法没有实现或者不支持相应的操作,那么python就会调用b的__radd__()方法。
【例子】
class Nint(int):
def __radd__(self,other):
return int.__sub__(other,self) #注意self在后面
a = Nint(5)
b = Nint(3)
print(a + b) # 8
print(1 + b) # -2
# 结果没有看懂没有看懂
iadd(self, other)定义赋值加法的行为:+=
isub(self, other)定义赋值减法的行为:-=
imul(self, other)定义赋值乘法的行为:*=
itruediv(self, other)定义赋值真除法的行为:/=
ifloordiv(self, other)定义赋值整数除法的行为://=
imod(self, other)定义赋值取模算法的行为:%=
ipow(self, other[, modulo])定义赋值幂运算的行为:**=
ilshift(self, other)定义赋值按位左移位的行为:<<=
irshift(self, other)定义赋值按位右移位的行为:>>=
iand(self, other)定义赋值按位与操作的行为:&=
ixor(self, other)定义赋值按位异或操作的行为:^=
ior(self, other)定义赋值按位或操作的行为:|=
neg(self)定义正号的行为:+x
pos(self)定义负号的行为:-x
abs(self)定义当被abs()调用的时候
invert(self)定义按位求反的行为:~x
getattr(self,name):定义当用户试图获取一个不存在的属性的行为;
getattribute(self,name):定义当该类的属性被访问的时候(先调用该方法,查看是否存在该属性,若不存在,接着去调用__getattr__)。
setattr(self,name,value):定义当一个属性被设置时的行为
delattr(self,name): 定义当一个属性被删除时的行为
【例子】
class C:
def __getattribute__(self,item):
print('__getattribute__')
return super().__getattribute__(item)
def __getattr__(self,item):
print('__getattr__')
def __setattr__(self,key,value):
print('__setattr__')
super().__setattr__(key,value)
def __delattr__(self,item):
print('__delattr__')
super().__delattr__(item)
c = C()
c.x
# __getattribute__
# __getattr__
c.x = 1
# __setattr__
del c.x
# __delattr__
** 采用object(所有类的基类)调用方法,super()也是用来调用方法**
描述符就是将某种特殊类型的类的实例指派给另一个类的属性。
get(self, instance, owner)用于访问属性,它返回属性的值。
set(self, instance, value)将在属性分配操作中调用,不返回任何内容。
del(self, instance)控制删除操作,不返回任何内容。
【例子】
class MyDecriptor:
def __get__(self,instance,owner):
print('__get__',instance,owner)
def __set__(self,instance,value):
print('__set__',self,instance,value)
def __delete__(self,instance):
print('__delete__',self,instance)
class Test:
x = MyDecriptor():
t = Test()
t.x
# __get__<__main__.MyDecriptor object at 0x000000CEAAEB6B00> <__main__.Test object at 0x000000CEABDC0898>
t.x = 'x-man'
# __set__ <__main__.MyDecriptor object at 0x00000023687C6B00> <__main__.Test object at 0x00000023696B0940> x-man
del t.x
# __delete__ <__main__.MyDecriptor object at 0x000000EC9B160A90> <__main__.Test object at 0x000000EC9B160B38>
协议(Protocols)与其他编程语言中的接口很相似,它规定你哪些方法必须要定义。然而,在python中的协议就显得那么不正式。在Python中,协议更像是一种指南。
class CountList:
def __init__(self,*args):
self.values = [x for in args]
self.count = {}.fromkeys(range(len(self.values)),0)
def __len__(self):
return len(self.values)
def __getitem__():
self.count[item] +=1
return self.values[item]
c1 = CountList(1,3,5,7,9)
c2 = CountList(2,4,6,8,10)
print(c1[1]) # 3
print(c2[2]) # 6
print(c1[1]+c2[1]) # 7
print(c1.count) # {0:0,1:2,2:0,3:0,4:0}
print(c2.count) # {0:0,1:1,2:1,3:0,4:0}
len(self)定义当被len()调用时的行为(返回容器中元素的个数)
getitem(self,key)定义获取容器中元素的行为,相当于self[key]
setitem(self, key, value)定义设置容器中指定元素的行为,相当于self[key] = value。
delitem(self, key)定义删除容器中指定元素的行为,相当于del self[key]。
【例子】编写一个可改变的自定义列表,要求记录列表中每个元素被访问的次数
class CountList:
def __init__(self,*args):
self.values = [x for i in args]
self.count = {}.fromkeys(range(len(self.values)),0)
def __len__(self):
return len(self.values)
def __getitem__(self,item):
self.count[item] += 1
return self.values[item]
def __setitem__(self,key,value):
self.values[key] = value
def __delitem__(self,key):
del self.values[key]
for i in range(0,len(self.values)):
if i >=key:
self.count[i] = self.count[i+1]
self.count.pop(len(self.values))
c1 = CountList(1,3,5,7,9)
c2 = CountList(2,4,6,8,10)
print(c1[1]) # 3
print(c2[2]) # 6
c1 = CountList(1, 3, 5, 7, 9)
c2 = CountList(2, 4, 6, 8, 10)
print(c1[1]) # 3
print(c2[2]) # 6
c2[2] = 12
print(c1[1] + c2[2]) # 15
print(c1.count)
# {0: 0, 1: 2, 2: 0, 3: 0, 4: 0}
print(c2.count)
# {0: 0, 1: 0, 2: 2, 3: 0, 4: 0}
del c1[1]
print(c1.count)
# {0: 0, 1: 0, 2: 0, 3: 0}
迭代器是Python中最强大的功能之一,是访问集合元素的一种方式
迭代器是一个可以记住遍历的位置的对象
迭代器对象从集合的第一个元素开始访问,知道所有的元素被访问结束
迭代器只能往前不会后退
字符串,列表,字典或元祖对象都可用于作为创建迭代器
string = 'lsgogroup'
for c in string:
print(c)
'''
l
s
g
o
g
r
o
u
p
'''
for c in iter(string):
print(c)
【例子】
links = {'B':'baidu,'A':'alibaba','T':'Tencent'}
for each in link:
print('%s ->%s' %(each,links[each]))
# B -> 百度
# A -> 阿里
# T -> 腾讯
for each in iter(links):
print('%s -> %s' % (each, links[each]))
links = {'B':'baidu','A':'Alibaba','T':'Tencent'}
it = iter(links)
print(next(it)) # B
print(next(it)) # A
print(next(it)) # T
print(next(it)) # StopIteration
it = iter(links)
while true:
try:
each = next(it)
except StopIteration:
break
print(each)
# B
# A
# T
把一个类作为一个迭代器使用需要在类中实现两个魔方方法__ietr__()与__next__()
iter(self)定义当迭代容器中的元素的行为,返回一个特殊的迭代器对象, 这个迭代器对象实现了 next() 方法并通过 StopIteration 异常标识迭代的完成。
next() 返回下一个迭代器对象。
StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在 next() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。
【例子】
class Fibs:
def __init__(self,n=10):
self.a = 0
self.b = 1
self.n = n
def __iter__(self):
return self
def __next__(self):
self.a,self.b = self.b, self.a+self.b
if self.a > self.n:
raise StopIteration
return self.a
fibs = Fibs(100)
for each in fibs:
print(each,end = ' ')
# 1 1 2 3 8 13 21 34 55 89
在Python中,使用了yield的函数被称为生成器(generator)。
跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
在调用生成器运行的过程中,每次遇到yield时函数会暂停并保存当前所有的运行信息,返回yield的值,并在下一次执行next()方法时从当前位置继续运行。
调用一个生成器函数,返回的是一个迭代器对象
【例子】
def myGen():
print('生成器执行!')
yield 1
yield 2
myG = myGen()
print(next(myG))
# 生成器执行!
# 1
print(next(myG))
# 2
print(next(myG))
# StopIteration
myG = myGen()
for each in myG:
print(each)
# 生成器执行
# 1
# 2
【例子】
def libs(n):
a = 0
b = 1
while True:
a,b = b,a+b
if a>n:
return
yield a
for each in libs(100):
print(each,end = ' ')
# 1 1 2 3 5 8 13 21 34 55 89
1、上面提到了许多魔法方法,如__new__,init, str,rstr,getitem,__setitem__等等,请总结它们各自的使用方法。
2、利用python做一个简单的定时器类
要求:
定制一个计时器的类。
start和stop方法代表启动计时和停止计时。
假设计时器对象t1,print(t1)和直接调用t1均显示结果。
当计时器未启动或已经停止计时时,调用stop方法会给予温馨的提示。
两个计时器对象可以进行相加:t1+t2。
只能使用提供的有限资源完成。
模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py。模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用 Python 标准库的方法。
容器–>数据的封装
函数–>语句的封装
类—>属性和方法的封装
模块–>程序文件
【例子】创建一个hello.py文件
hello.py
def hi():
print('Hi,everyone,I Love Isgogroup')
命名空间因为对象的不同,也有所区别,分为如下几种:
内置命名空间(Built-in NameSpace):Python运行起来,他们就存在了。内置函数的命名空间都属于内置命名空间,所以我们可以在任何程序中直接运行它们,比如Id()不需要做什么操作,拿过来就直接使用了。
全局命名空间(modual :Global NameSpace):每个创建它自己所拥有的全局命名空间,不同模块的全局命名空间彼此相互独立,不同模块中相同名称的命名空间,也会因为模块的不同而不相互干扰。
本地命名空间(Function & Class: Local NameSpaces):模块中有函数或者类,每个函数或者类所定义的命名空间就是本地命名空间。如果函数返回了结果或者抛出异常,则本地命名空间也就结束了。
程序在查询上述三种命名空间的时候,就按照从里到位的顺序,即:Local NameSpaces–>Global NamesSpaces—>Built-in-NameSpaces。
【例子】
import hello
hello.hi() # Hi everyone,I love Lsgogroup
hi() # NameError: name 'hi' is not defined
【例子】创建一个模块 TemperatureConversion.py
# TempratureConversion.py
def c2f(cel):
fah = cel*1.8 +32
return fah
def f2c(fah):
cel = (fah-32)/ 1.8
import TempratureConversion
print('32摄氏度 = %.2f华氏度' % TempratureConversion.c2f(32))
print('99华氏度 = %.2f摄氏度' % TempratureConversion.f2c(99))
# 32摄氏度 = 89.6华氏度
# 00华氏度 = 37.22摄氏度
【例子】
from TemperatureConversion import c2f, f2c
print('32摄氏度 = %.2f华氏度' % c2f(32))
print('99华氏度 = %.2f摄氏度' % f2c(99))
# 32摄氏度 = 89.60华氏度
# 99华氏度 = 37.22摄氏度
import TempratureConversion as tc
print('32摄氏度 = %.2f华氏度' % tc.c2f(32))
print('99华氏度 = %.2f摄氏度' % tc.f2c(99))
# const.py文件
PI = 3.14
def main():
print("PI: ",PI)
main()
# PI: 3.14
现在,我们写一个用于计算圆面积的area.py文件,area.py文件需要用到const.py文件中的PI变量。从const.py中,我们把PI变量导入area.py:
from const import PI
def calc_round_area(radius):
return PI*(radius **2)
def main():
print('round area',calc_round_area(2))
main()
PI:3.14
round area: 12.56
我们看到const.py中的main函数也被运行了,实际上不希望它被执行,因为const.py提供的main函数只是为了测试常量定义。这时 if __name__ ==' __main__'派上了用场,我们把const.py改一下,添加 if __name__ =='__main__':
```py
# 修改const.py文件
PI = 3.14
def main():
print("PI:", PI)
if __name__ == "__main__":
main()
运行 const.py,输出如下:
PI: 3.14
运行 area.py,输出如下:
round area: 12.56
name:是内置变量,可用于表示当前模块的名字
import const
print(__name__)
# __main__
print(const.__name__)
# const
a
├── b
│ ├── c.py
│ └── __init__.py
└── __init__.py
在Package(包)中,文件c.py,init.py,init.py的内容都为:
print(name)
当一个.py文件(模块)被其他.py文件(模块)导入时,我们在命令行执行:
Python -c "import a.b.c"
# a
# a.b
# a.b.c
由此可见:name__可以清晰地反映一个模块在包中的层次。
3. main.py文件与Python -m
Python的-m参数用于将一个模块或者包作为一个脚本执行,而__main.py文件相当于是一个包"入口程序"。
运行Python程序的两种方式:
python xxx.py,直接运行xxx.py文件
python -m xxx.py,把xxx.py当做模块运行
4. mian.py的作用
一个包的结构:
package
├── init.py
└── main.py
其中文件__init__.py的内容
import sys
print("__init__")
print(sys.path)
其中文件__main__.py的内容:
import sys
print("__main__")
print(sys.path)
接下来,我们运行这个package,使用python -m package运行,输出结果:
__init__
['', ...]
__main__
['', ...]
使用python package运行,输出结果:
__main__
['package', ...]
【小结】
当加上-m参数时,Python会把当前工作目录添加到sys.path中;而不加-m时,Python则会把脚本所在目录添加到sys.path中。
当加上-m参数时,Python会先将模块或者包导入,然后再执行。
main.py文件是一个包或者目录的入口程序。不管是用python package还是用python -m package运行,main.py文件总是被执行。
【参考来源】:https://blog.csdn.net/yjk13703623757/article/details/77918633
当解释器遇到import语句,如果模块在当前的搜索路径就会被导入。
【例子】
import sys
print (sys.path)
我们使用 import 语句的时候,Python 解释器是怎样找到对应的文件的呢?
这就涉及到 Python 的搜索路径,搜索路径是由一系列目录名组成的,Python 解释器就依次从这些目录中去寻找所引入的模块。
这看起来很像环境变量,事实上,也可以通过定义环境变量的方式来确定搜索路径。
搜索路径是在 Python 编译或安装的时候确定的,安装新的库应该也会修改。搜索路径被存储在 sys 模块中的 path 变量中。
包是一种管理Python模块命名空间的形式,采用“点模块名称”。
创建包分为三个步骤:
创建一个文件夹,用于存放相关的模块,文件夹的名字即包的名字。
在文件夹中创建一个 init.py 的模块文件,内容可以为空。
将相关的模块放入文件夹中。
【包的创建模板】
sound/ 顶层包
__init__.py 初始化 sound 包
formats/ 文件格式转换子包
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ 声音效果子包
__init__.py
echo.py
surround.py
reverse.py
...
filters/ filters 子包
__init__.py
equalizer.py
vocoder.py
karaoke.py
...
在导入一个包的时候,Python会根据sys.path中的目录来寻找这个包中包含的子目录。
【访问包中模块】
访问一:目录只有包含一个叫做 init.py 的文件才会被认作是一个包,最简单的情况,放一个空的 init.py 就可以了。
import sound.effects.echo
这将会导入子模块 sound.effects.echo。 他必须使用全名去访问:
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
访问二:导入子模块:from sound.effects import echo,是直接导入本文件中,会有担心函数名重复
这同样会导入子模块: echo,但是不再不需要那些冗长的前缀,所以可以这样使用:
echo.echofilter(input, output, delay=0.7, atten=4)
访问三:直接导入一个函数或者变量:from sound.effects.echo import echofilter
同样的,这种方法会导入子模块: echo,并且可以直接使用他的 echofilter() 函数:
echofilter(input, output, delay=0.7, atten=4)
【注意】
注意当使用 from package import item 这种形式的时候,对应的 item 既可以是包里面的子模块(子包),或者包里面定义的其他名称,比如函数,类或者变量。
设想一下,如果我们使用 from sound.effects import * 会发生什么?
Python 会进入文件系统,找到这个包里面所有的子模块,一个一个的把它们都导入进来。
导入语句遵循如下规则:如果包定义文件 init.py 存在一个叫做 all 的列表变量,那么在使用 from package import * 的时候就把这个列表中的所有名字作为包内容导入。
这里有一个例子,在 sounds/effects/init.py中包含如下代码:
all = [“echo”, “surround”, “reverse”]
这表示当你使用 from sound.effects import *这种用法时,你只会导入包里面这三个子模块。
如果 all 真的没有定义,那么使用from sound.effects import *这种语法的时候,就不会导入包 sound.effects 里的任何子模块。他只是把包 sound.effects 和它里面定义的所有内容导入进来(可能运行__init__.py里定义的初始化代码)。
这会把 init.py 里面定义的所有名字导入进来。并且他不会破坏掉我们在这句话之前导入的所有明确指定的模块。
import sound.effects.echo
import sound.effects.surround
from sound.effects import *
这个例子中,在执行 from…import 前,包 sound.effects 中的 echo 和 surround 模块都被导入到当前的命名空间中了。
通常我们并不主张使用 * 这种方法来导入模块,因为这种方法经常会导致代码的可读性降低。
1、怎么查出通过 from xx import xx导⼊的可以直接调⽤的⽅法?
2、了解Collection模块,编写程序以查询给定列表中最常见的元素。
题目说明:
输入:language = [‘PHP’, ‘PHP’, ‘Python’, ‘PHP’, ‘Python’, ‘JS’, ‘Python’, ‘Python’,‘PHP’, ‘Python’]
输出:Python
“”"
Input file
language = [‘PHP’, ‘PHP’, ‘Python’, ‘PHP’, ‘Python’, ‘JS’, ‘Python’, ‘Python’,‘PHP’, ‘Python’]
Output file
Python
“”"
def most_element(language):
“”" Return a list of lines after inserting a word in a specific line. “”"
# your code here