“Python基础”的版本间的差异
(→E5 =) |
(→E5) |
||
第425行: | 第425行: | ||
'with.py', | 'with.py', | ||
'test__file__.py'] | 'test__file__.py'] | ||
+ | |||
+ | os.walk | ||
+ | <pre> | ||
+ | import os | ||
+ | import fnmatch | ||
+ | |||
+ | pys=['*.py','*.pyw'] | ||
+ | matches = [] | ||
+ | |||
+ | for root, dirnames, filenames in os.walk(os.path.expanduser("/home/evan/data/tmp/py")): | ||
+ | for extensions in pys: | ||
+ | for filename in fnmatch.filter(filenames, extensions): | ||
+ | matches.append(os.path.join(root, filename)) | ||
+ | |||
+ | print(matches) | ||
+ | |||
+ | '/home/evan/data/tmp/py/md5.py', '/home/evan/data/tmp/py/pe.py', '/home/evan/data/tmp/py/get10.py', '/home/evan/data/tmp/py/pscp.py', '/home/evan/data/tmp/py/p.py', '/home/evan/data/tmp/py/read_from_fileinput2.py', '/home/evan/data/tmp/py/read_stdin2.py', '/home/evan/data/tmp/py/pp.py', '/home/evan/data/tmp/py/read_from_fileinput.py', '/home/evan/data/tmp/py/default_logging.py'] | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | </pre> | ||
===chapter 11 === | ===chapter 11 === |
2024年10月30日 (三) 03:20的版本
目录
- 1 2024
- 2 Python项目读取配置方式
- 3 python中字典的循环遍历的两种方式
- 4 python3 遍历列表list 四种方法
- 5 python文件操作
- 6 Python 函数返回值
- 7 py linux系统管理
- 8 range
- 9 learn
- 9.1 Apr 2024
2024
https://liaoxuefeng.com/books/python/function/recursive-function/index.html
https://github.com/qiwsir/itdiffer/blob/main/self-learning.md
recursive暂时跳过
project 2024
github/python/project/chapter25CGI/2024
Python format 格式化函数
一种格式化字符串的函数 str.format(),它增强了字符串格式化的功能。 基本语法是通过 {} 和 : 来代替以前的 % 。 "{} {}".format("hello", "world") # 不设置指定位置,按默认顺序 'hello world' eg 2 print("""Content-type: text/html <html> <head> <title>Simple Edit</title> </head> <body> <form method="post" action="simple_edit.cgi" method="POST"> <textarea name="text" rows="20" cols="20">{}</textarea> <br /> <input type="submit" > </form> </body> </html> """.format(text))
https://www.runoob.com/python/att-string-format.html
abspath
In [1]: import os In [2]: os.path.abspath("w.py") Out[2]: '/home/evan/data/python/cgi/w.py' In [3]: ls 1.cgi* edit.cgi index.html powers.py save.cgi simple_edit.cgi* simple_edit.dat w.py*
https://stackoverflow.com/questions/51520/how-to-get-an-absolute-file-path-in-python
threading
import threading import requests # 目标URL列表 urls = [ "http://www.google.com", "http://www.bing.com", "http://www.stackoverflow.com", # 添加更多URL ] # 检查URL可达性的函数 def check_url(url): try: response = requests.get(url, timeout=5) if response.status_code == 200: print(f"{url} is up and running.") else: print(f"{url} returned status code {response.status_code}.") except requests.RequestException as e: print(f"{url} is down. Error: {e}") # 创建线程列表 threads = [] # 为每个URL创建并启动一个线程 for url in urls: thread = threading.Thread(target=check_url, args=(url,)) threads.append(thread) thread.start() # 等待所有线程完成 for thread in threads: thread.join() print("All URLs have been checked.")
Python项目读取配置方式
常见的是 import configparser
python中字典的循环遍历的两种方式
1. 只对键的遍历 一个简单的for语句就能循环字典的所有键,就像处理序列一样: In [1]: d = {'name1' : 'pythontab', 'name2' : '.', 'name3' : 'com'} ...: for key in d: ...: print (key, ' value : ', d[key]) ...: name1 value : pythontab name2 value : . name3 value : com 2. 对键和值都进行遍历 如果只需要值,可以使用d.values,如果想获取所有的键则可以使用d.keys。 如果想获取键和值d.items方法会将键-值对作为元组返回,for循环的一大好处就是可以循环中使用序列解包。 代码实例: or key, value in d.items(): print (key, ' value : ', value) name1 value : pythontab name2 value : . name3 value : com
python3 遍历列表list 四种方法
python文件操作
python读取文件
Python 函数返回值
py linux系统管理
In [6]: [item for item in os.listdir(os.path.expanduser('/tmp')) if os.path.isdir(item)] Out[6]: [] In [7]: [item for item in os.listdir(os.path.expanduser('/tmp')) if os.path.isdir(item)] Out[7]: [] 打印最常用10条命令 import os from collections import Counter c = Counter() # 读取bash历史记录文件并统计命令频率 with open(os.path.expanduser('~/.bash_history')) as f: for line in f: # whith open(os.path.expanduser(' ~/.bash_history')) as f: cmd = line.strip().split() if cmd: c[cmd[0]] += 1 print(c.most_common(10)) # with open('example.txt', 'r') as file: # content = file.read() # print(content) # [('ls', 352), ('cd', 309), ('bash', 161), ('cat', 114), ('vim', 78), ('sudo', 54), ('vi', 46), ('geany', 33), ('ssh', 31), ('python3', 27)] # [('ls', 352), ('cd', 309), ('bash', 161), ('cat', 114), ('vim', 78), ('sudo', 54), ('vi', 46), ('geany', 33), ('ssh', 31), ('python3', 27)] # [('ls', 352), ('cd', 309), ('bash', 162), ('cat', 114), ('vim', 78), ('sudo', 54), ('vi', 46), ('geany', 33), ('ssh', 31), ('python3', 27)] def execute_cmd(cmd): p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout,stderr = p.communicate() if p.returncode != 0: return p.returncode, stderr return p.returncode, stdout 函数定义 def execute_cmd(cmd):定义了一个名为execute_cmd的函数,它接受一个参数cmd,这个参数应该是一个表示命令的字符串或者是一个可以被当作命令执行的对象(在shell=True的情况下)。 subprocess.Popen调用 p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 这行代码使用subprocess模块创建了一个新的子进程来执行命令。 shell=True表示命令将在一个 shell 环境中执行。这使得可以执行一些复杂的 shell 命令,比如包含管道、重定向等操作的命令。 stdin=subprocess.PIPE、stdout=subprocess.PIPE和stderr=subprocess.PIPE分别表示将子进程的标准输入、标准输出和标准错误流连接到管道,以便可以获取和处理这些输出和错误信息。 p.communicate调用 stdout,stderr = p.communicate() 这个方法用于与子进程进行通信,它会等待子进程完成,并返回一个包含标准输出和标准错误的元组。 在这里,stdout将获取子进程的标准输出内容,stderr将获取子进程的标准错误内容。 返回值处理 if p.returncode!= 0: 这里检查子进程的返回码。如果返回码不为 0,说明命令执行过程中出现了错误。 在这种情况下,return p.returncode, stderr会返回子进程的返回码和标准错误信息。 return p.returncode, stdout 如果子进程的返回码为 0,说明命令执行成功,此时会返回子进程的返回码和标准输出信息。 这段代码的主要功能是执行一个命令,并根据命令执行的结果返回相应的信息。如果命令执行成功,返回命令的返回码和标准输出;如果命令执行失败,返回命令的返回码和标准错误。
depoly_mongodb.py
#!/usr/bin/env python #-*- coding:utf-8 -*- from __future__ import print_function import os import shutil import subprocess import tarfile def execute_cmd(cmd): p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout,stderr = p.communicate() if p.returncode != 0: return p.returncode, stderr return p.returncode, stdout def unpackage_mongo(package, package_dir): unpackage_dir = os.path.splitext(package)[0] if os.path.exists(package_dir): shutil.rmtree(package_dir) if os.path.exists(papckage_dir): shutil.rmtree(package_dir) t = tarfile.open(package,'r:gz') t.extractall('.') shutil.move(unpackage_dir, package_dir) def create_datadir(data_dir): if os.path.exists(data_dir): shutil.rmtree(data_dir) os.makedirs(data_dir) def forma_mongod_command(package_dir, data_dir, logfile): mongod = os.path.join(package_dir, 'mongod') mongod_format = """{0} --fork --dbpath {1} --logpath {2}""" return mongod_format.format(mongod, data_dir, logfile) def start_mongo(cmd): returncode, out = execute_cmd(cmd) if returncode != 0: raise SystemExit('execute {0} error :{1}'.format(cmd, out)) else: print('execute {0} success'.format(cmd)) def main(): package = 'mongodb-linux-x86_64-debian11-5.0.29.tgz' #package = 'https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.2.10.tgz' curl_dir = os.path.abspath('.') package_dir = os.path.join(curl_dir, 'mongo') data_dir = os.path.join(cur_dir, 'mongodata') logfile = os.path.join(data_dir,'mongod.log') if not os.paht.exists(package): raise SystemExit(" {0} not found ", format(package)) unpackage_mongo(package, package_dir) if __name__ == '__main__': main() # 代码解读 unpackage_dir = os.path.splitext(package)[0] # 以下是对这段代码的解读: # os.path.splitext(package) # 这是 Python 中os.path模块提供的一个函数。它的作用是将文件名(这里是package变量所代表的文件名)拆分成文件名和扩展名两部分。 # 例如,如果package是"example.txt",那么os.path.splitext(package)将返回("example", ".txt")。 # unpackage_dir = os.path.splitext(package)[0] # 这里取os.path.splitext(package)返回结果的第一个元素。 # 继续上面的例子,如果package是"example.txt",那么unpackage_dir将被赋值为"example"。 # 其目的通常是获取文件名中除去扩展名的部分,可能是为了进一步操作,比如创建一个与该文件名(除去扩展名)相关的目录等。
文本处理
In [39]: import os p75 In [40]: [ item for item in os.listdir('.') if item.endswith('.py')] Out[40]: ['1.py', 'checkprocess.py', 'dump.py', 'judge.py', 'rename.py', 'devresize.py', # 在不在另外一个str 中用in or not in In [45]: 'in' in s Out[45]: True In [46]: "".join(['a','b','c']) Out[46]: 'abc' In [47]: str.join? Signature: str.join(self, iterable, /) Docstring: Concatenate any number of strings. The string whose method is called is inserted in between each given string. The result is returned as a new string. Example: '.'.join(['ab', 'pq', 'rs']) -> 'ab.pq.rs' Type: method_descriptor In [54]: from collections import Counter In [55]: c = Counter('abcba') In [56]: c Out[56]: Counter({'a': 2, 'b': 2, 'c': 1}) In [57]: c['a'] += 1 In [58]: c Out[58]: Counter({'a': 3, 'b': 2, 'c': 1}) In [59]: c.most_common(2) Out[59]: [('a', 3), ('b', 2)] 字符串格式化 In [5]: "{} is better than {}. {} is better than {}.". format('Beaufiful', 'ugly', 'explicit', 'implicit') Out[5]: 'Beaufiful is better than ugly. explicit is better than implicit.'
re
In [6]: import re In [7]: data = "what is the difference between pyuthon 2.7.12 and python 3.6 ?" In [10]: re.findall('python [0-9]\.[0-9]\.[0-9]',data) <>:1: SyntaxWarning: invalid escape sequence '\.' <ipython-input-10-15bd1c311994>:1: SyntaxWarning: invalid escape sequence '\.' re.findall('python [0-9]\.[0-9]\.[0-9]',data) Out[10]: [] In [11]: re.findall('python',data) Out[11]: ['python'] import re def main(): pattern = "[0-9]+" re_obj = re.compile(pattern) with open('data.txt') as f: for line in f: print(re_obj.findall(line)) if __name__ == '__main__': main() # ➜ tmp py3 re_compile.py # ['12234'] # ['22222'] # ['3333'] # ➜ tmp cat data.txt # dafasf12234 # ddd22222 # 3333dddd% >>> import re >>> import re,requests >>> r = requests.get('https://news.ycombinator.com/') >>> >>> re.findall('"(https?://.*?)"',r.content)
chapter 5
E5
In [2]: import glob
In [3]: glob.glob('*.py') Out[3]: ['1.py',
'deploy-mongo.py', '2.py', 'moni-php.py', 'c.py', 'errmv.py', 'with.py', 'test__file__.py']
os.walk
import os import fnmatch pys=['*.py','*.pyw'] matches = [] for root, dirnames, filenames in os.walk(os.path.expanduser("/home/evan/data/tmp/py")): for extensions in pys: for filename in fnmatch.filter(filenames, extensions): matches.append(os.path.join(root, filename)) print(matches) '/home/evan/data/tmp/py/md5.py', '/home/evan/data/tmp/py/pe.py', '/home/evan/data/tmp/py/get10.py', '/home/evan/data/tmp/py/pscp.py', '/home/evan/data/tmp/py/p.py', '/home/evan/data/tmp/py/read_from_fileinput2.py', '/home/evan/data/tmp/py/read_stdin2.py', '/home/evan/data/tmp/py/pp.py', '/home/evan/data/tmp/py/read_from_fileinput.py', '/home/evan/data/tmp/py/default_logging.py']
chapter 11
上下文
with open('file1','r') as source, open('file2','w') as target: target.write(source.read())
mysql
import os import pymysql as db # if os.getenv('DB','MySQL') == 'MySQL': # import MySQLdb as db # else: # import sqlite3 as db def get_conn(**kwargs): if os.getenv('DB', 'MySQL') == 'MySQL': return db.connect(host=kwargs.get('host', 'localhost'), user=kwargs.get('user'), passwd=kwargs.get('passwd'), port=kwargs.get('port', 3306), db=kwargs.get('db')) else: return db.connect(database=kwargs.get('db')) def main(): conn = get_conn(host='127.0.0.1', user='root', passwd='evan2240881', port=3306, db='bbs') # get cursor object cur = conn.cursor() # execute SQL statement cur.execute("select * from messages") print(cur.fetchall()) # close resources cur.close() conn.close() if __name__ == '__main__': main() # tmp py3 connect_mysql.py # ((1, '', '', None, ''), (2, '2', 'evan', None, 'evan'))
range
learn
py作为很多开发项目的辅助语言现在来说会更流行一些,不管是github还是其他地方。所以,你能找到的帮助,解决问题的思路也比perl广。 追问 python 自学容易么,可否推荐基本书看看 追答 首先我推荐你从这边开始入门,我以前也是这边看。http://woodpecker.org.cn/abyteofpython_cn/chinese/index.html, 自学容易的。 ,不需要急,等大部分了解后,并且使用py写脚本一段时间之后,你会开始需要更多模块的用法,这时候到 https://docs.python.org/2.7/ 这里查。 书的话,我觉得如果你想成为语法大师的话,O'REILLY 的 跟 这两本, 不会的问题,用google搜,特别是Stack Overflow 的站点上搜往往能找到答案。 当觉得已经对py很熟悉之后,可以看别人的py项目。然后用一些好用的框架比如django啥的,那么就合格了。然后模块就是越用越熟悉
Apr 2024
tuple 英 [tjʊpəl; ˈtʌpəl] 美 [ˈtjʊpəl; ˈtʌpəl] n. [计] 元组,重数
安装 VS Code Python
str
In [3]: s = "hello" In [4]: s[0] = 'H' --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-4-d6f3b193531a> in <module> ----> 1 s[0] = 'H' TypeError: 'str' object does not support item assignment In [5]: s = 'H' + s[1:] In [6]: s Out[6]: 'Hello' In [7]: s = "Hello, world" In [8]: s[:5] Out[8]: 'Hello' In [9]: s[::-1] Out[9]: 'dlrow ,olleH' In [10]: ''.join(reversed(s)) Out[10]: 'dlrow ,olleH' In [11]:
list
与Python字符串不一样的是,列表中的元素是可以改变的
def reverseWords(input): inputWords = input.split() inputWords=inputWords[-1::-1] output= ' '.join(inputWords) return output if __name__ == "__main__": input = 'I love evan' rw = reverseWords(input) print(rw) ''' evan love I # 翻转字符串 # 假设列表 list = [1,2,3,4], # list[0]=1, list[1]=2 ,而 -1 表示最后一个元素 list[-1]=4 ( 与 list[3]=4 一样) # inputWords[-1::-1] 有三个参数 # 第一个参数 -1 表示最后一个元素 # 第二个参数为空,表示移动到列表末尾 # 第三个参数为步长,-1 表示逆向 https://www.runoob.com/python3/python3-data-type.html '''
Tuple(元组)
元组(tuple)与列表类似,不同之处在于元组的元素不能修改。元组写在小括号 () 里,元素之间用逗号隔开。
元组中的元素类型也可以不相同
tup2 = (20,) # 一个元素,需要在元素后添加逗号 如果你想创建只有一个元素的元组,需要注意在元素后面添加一个逗号,以区分它是一个元组而不是一个普通的值,这是因为在没有逗号的情况下,Python会将括号解释为数学运算中的括号,而不是元组的表示。 如果不添加逗号,如下所示,它将被解释为一个普通的值而不是元组: not_a_tuple = (42)
修改元组
元组中的元素值是不允许修改的,但我们可以对元组进行连接组合
https://www.runoob.com/python3/python3-tuple.html
Dictionary
Python3 条件控制
match...case
Python 3.10 增加了 match...case 的条件判断,不需要再使用一连串的 if-else 来判断了
def http_error(status): match status: case 400: return "bad request" case 404: return "not Found" case 418: return "I am a teapot" case _: return "something's wrong with the internet" mystatus=400 print(http_error(mystatus)) # bad request
Python3 循环语句
斐波纳契数列 n=3 a, b = 0,1 for i in range(n): print("斐波纳契数列为%d"%(b)) a,b = b,a+b print("a is %d b is %d" %(a,b)) ''' 其中代码 a, b = b, a+b 的计算方式为先计算右边表达式,然后同时赋值给左边,等价于: n=b m=a+b a=n b=m ''' [Running] /usr/bin/python3 "/home/evan/tmp/py/2.py" 斐波纳契数列为1 a is 1 b is 1 斐波纳契数列为1 a is 1 b is 2 斐波纳契数列为2 a is 2 b is 3
Python 推导式
Python3 迭代器与生成器
Python3 函数
def area(width, height): return width * height def print_welcome(name): print("welcome",name) print_welcome("evan") w = 4 h = 5 print("width =", w, "height =", h , "area =", area(w,h)) welcome evan width = 4 height = 5 area = 20
x = lambda a : a + 10 print(x(5)) # Output: 15
强制位置参数
https://www.runoob.com/python3/python3-function.html
https://zhuanlan.zhihu.com/p/412273465
参数传递
python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。
参数
以下是调用函数时可使用的正式参数类型:
必需参数 关键字参数 默认参数 不定长参数
必需参数
关键字参数
键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值
def printinfo( name, age): print ("name:", name) print ("age:", age ) printinfo( age=40, name="nick") name: nick age: 40
默认参数
def printinfo( name, age=33): print ("name:", name) print ("age:", age ) printinfo( age=40, name="nick") print("88888888888888") printinfo( name="evan") name: nick age: 40 88888888888888 name: evan age: 33
不定长参数
你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述 2 种参数不同,声明时不会命名。基本语法如下: def functionname([formal_args,] *var_args_tuple ): "函数_文档字符串" function_suite return [expression] 加了星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。 def printinfo( arg1, *vartuple ): print("输出") print(arg1) print(vartuple) printinfo( 70,60,50) 输出 70 (60, 50) 还有一种就是参数带两个星号 **基本语法如下: def functionname([formal_args,] **var_args_dict ): "函数_文档字符串" function_suite return [expression] 加了两个星号 ** 的参数会以字典的形式导入 def printinfo( arg1, **vardict ): print("输出") print(arg1) print(vardict) printinfo( 70,a=33,b=50) 输出 70 {'a': 33, 'b': 50}
匿名函数
Python 使用 lambda 来创建匿名函数。
所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
lambda 只是一个表达式,函数体比 def 简单很多
语法 lambda 函数的语法只包含一个语句,如下: lambda [arg1 [,arg2,.....argn]]:expression 设置参数 a 加上 10: 实例 x = lambda a : a + 10 print(x(5)) sum = lambda arg1, arg2: arg1 + arg2 print("相加后的value" ,sum( 10, 20)) print("相加后的value" ,sum( 20, 30))
return 语句
def sum( arg1, arg2 ): total = arg1 + arg2 print("函数内 : ",total) return total total = sum(10,20) print("函数外",total) 函数内 : 30 函数外 : 30
强制位置参数
Python3.8 新增了一个函数形参语法 / 用来指明函数形参必须使用指定位置参数,不能使用关键字参数的形式。 在以下的例子中,形参 a 和 b 必须使用指定位置参数,c 或 d 可以是位置形参或关键字形参,而 e 和 f 要求为关键字形参: def f(a, b, /, c, d, *, e, f): print(a, b, c, d, e, f) 以下使用方法是正确的: f(10, 20, 30, d=40, e=50, f=60) 以下使用方法会发生错误: f(10, b=20, c=30, d=40, e=50, f=60) # b 不能使用关键字参数的形式 f(10, 20, 30, 40, 50, f=60) # e 必须使用关键字参数的形式
Python lambda(匿名函数)
# x=lambda a : a + 10 # print(x(5)) # sum = lambda arg1, arg2: arg1 + arg2 # print("相加后的value" ,sum( 10, 20)) # print("相加后的value" ,sum( 20, 30)) # def sum( arg1, arg2 ): # total = arg1 + arg2 # print("函数内 : ",total) # return total # total = sum(10,20) # print("函数外",total) # 函数内 : 30 # 函数外 : 30 # x = lambda a : a + 1 # print(x(2)) # x = lambda a, b , c : a + b + c # print(x(5,6,2)) # numbers = [1,2,3,4,5] # squared = list(map(lambda x: x**2,numbers)) # print(squared) # # Output: [1, 4, 9, 16, 25] # numbers=[1,2,3,4,5,6,7,8] # even_numbrs = list(filter(lambda x: x % 2 ==0, numbers)) # print(even_numbrs) # # Output: [2, 4, 6, 8] from functools import reeuce numbers = [1,2,3,4,5] product = reduce(lambda x,y: x*y, numbers) print(product) # Output: 120
Python 装饰器
https://www.runoob.com/python3/python-decorators.html
语法 def decorator_function(original_function): def wrapper(*args, **kwargs): # 这里是在调用原始函数前添加的新功能 before_call_code() result = original_function(*args, **kwargs) # 这里是在调用原始函数后添加的新功能 after_call_code() return result return wrapper # 使用装饰器 @decorator_function def target_function(arg1, arg2): pass # 原始函数的实现 使用装饰器 装饰器通过 @ 符号应用在函数定义之前,例如: @time_logger def target_function(): pass 等同于: def target_function(): pass target_function = time_logger(target_function) 这会将 target_function 函数传递给 decorator 装饰器,并将返回的函数重新赋值给 target_function。从而,每次调用 target_function 时,实际上是调用了经过装饰器处理后的函数。 通过装饰器,开发者可以在保持代码整洁的同时,灵活且高效地扩展程序的功能 def repeat(n): def decorator(func): def wrapper(*args, **kwargs): for i in range(n): result = func(*args, **kwargs) return result return wrapper return decorator @repeat(3) def greet(name): print("Hello, " + name) greet("Evan") Hello, Evan Hello, Evan Hello, Evan
Python3 数据结构
Python3 模块
Python3 File(文件) 方法
Python3 面向对象
class MyClass: i = 12345 def f(self): return 'hello evan' x = MyClass() print("Myclass类的属性i 为:",x.i) print("Myclass类的方法f 的返回值为:",x.f()) Myclass类的属性i 为: 12345 Myclass类的方法f 的返回值为: hello evan