Open10
Python 文法
with の中で定義した変数はその中を出ても有効
# Online Python Playground
# Use the online IDE to write, edit & run your Python code
# Create, edit & delete files online
class Resource:
def __enter__(self):
self.resource = "hoge"
print(self.resource)
return self.resource
def __exit__(self, exc_type, exc_value, traceback):
print("Resource is now closed")
# Resourceクラスを使用してwithステートメントのスコープをテスト
with Resource() as res:
print("res in with: ", res)
test = "test"
print("test in with: ", test)
print("res in main: ", res) # withブロック外でaが存在するかを確認
print("test in main: ", test)
一方、メソッドの場合は、メソッドを出るとアクセスできなくなる。
def hoge():
a = 'a'
print("a in hoge method: ", a)
hoge()
print(a)
def gen_function(n):
print('start')
while n:
print(f'yield: {n}')
yield n
print("after n")
n -= 1
# for i in gen_function(2):
# print(i)
gen = gen_function(3)
next(gen)
next(gen)
next(gen)
# Output
# ```
# start
# yield: 3
# after n
# yield: 2
# after n
# yield: 1
# ```
# next(gen) # File "<exec>", line 24, in <module>
print([i**2 for i in gen_function(5)]) # [25, 16, 9, 4, 1]
print(gen(5))
def reader(src):
with open(src) as f:
for line in f:
yield line
def convert(line):
return line.upper()
def writer(dest, reader):
with open(dest, reader):
for line in reader:
f.write(convert(line))
writer('dest.txt', reader('src.txt'))
# 一行ずつメモリに展開されるので、大量のテキストデータでもメモリを圧迫せずに処理を行える
from dataclasses import dataclass
@dataclass
class Fruit:
name: str
price: int = 0
apple = Fruit(name="apple", price=128)
print(apple)
print(apple.name)
apple.price = 150
print(apple.price)
class Fruit:
def __init__(self, name, price):
self.name = name
self.price = price
banana = Fruit(name="banana", price=130)
print(banana)
print(banana.name)
banana.price = 160
print(banana.price)
def deco1(f):
print("deco1 called")
def wrapper():
print('before exec')
v = f()
print('after exec')
return v
return wrapper
@deco1
def func():
print('exec')
return 1
func()
def deco2(f):
def wrapper(*args, **kwargs):
print('before exec')
print("args: ", args)
print("kwargs: ", kwargs)
v = f(*args, **kwargs)
print('after exec')
return v
return wrapper
@deco2
def func2(x, y):
print('exec')
return x, y
func2(1, 2)
# args: (1, 2)
# kwargs: {}
@deco2
def func3(a: "a", b: "b"):
return a, b
func3(a="aa", b="bb")
# args: ()
# kwargs: {'a': 'aa', 'b': 'bb'}
# func3() # TypeError: func3() missing 2 required positional arguments: 'a' and 'b'
def deco3(z):
def _deco3(f):
def wrapper(*args, **kwargs):
print('before exec')
print("z: ", z)
print("args: ", args)
print("kwargs: ", kwargs)
v = f(*args, **kwargs)
print('after exec')
return v
return wrapper
return _deco3
@deco3(z='z')
def func4(x, y):
print('x, y: ', x, y)
return x, y
func4('あ', 'い')
from functools import wraps
def deco(f):
@wraps(f)
def wrapper(*args, **kwargs):
print('before exec')
v = f(*args, **kwargs)
print('after exec')
return v
return wrapper
@deco
def func():
"""func です"""
print("exec")
# @wraps(f)がない場合
print(func.__name__) # wrapper
print(func.__doc__) # None
# @wraps(f)がある場合
print(func.__name__) # func
print(func.__doc__) # func です
class TextField:
def __set_name__(self, owner, name):
print(f'__set_name__was called')
print(f'{owner=}, {name=}')
self.name = name
def __set__(self, instance, value):
print('__set__ was called')
if not isinstance(value, str):
raise AttibuteError('must be str')
instance.__dict__[self.name] = value
def __get__(self, instance, owner):
print('__get__ was called')
return instance.__dict__[self.name]
class Book:
title = TextField()
book = Book()
book.title = 'Harry Potter'
# 非データデスクリプタ
class TextField2:
def __init__(self, value):
if not isinstance(value, str):
raise AttributeError('must be str')
self.value = value
def __set_name__(self, owner, name):
print(f'__set_name__was called')
print(f'{owner=}, {name=}')
self.name = name
def __get__(self, instance, owner):
print('__get__ was called')
return self.value
class Book2:
title = TextField2('Python Book')
book = Book2()
book.title # __get__ was called
# インスタンス変数のセット
book.title = 'updated book'
print(book.title) # updated book __get__ は呼ばれない 上書きされる
from collections import defaultdict
# デフォルト値がNoneのdefaultdictを作成
my_dict = defaultdict(lambda: None)
print(my_dict['non_existent_key'])
# None
my_dict2 = {}
print(my_dict2['non_existent_key'])
# File "<exec>", line 9, in <module>
# KeyError: 'non_existent_key'
TypedDict について
from typing import TypedDict
class User(TypedDict):
name: str
age: int
user = User(name="sakai", age=30)
print(user["name"]) # sakai
使い方
user: User = {
"name": "Alice",
"age": 30,
"email": "alice@example.com"
}
型が違っていたらエラーになる。
hasattr について
class MyClass:
def __init__(self):
self.value = 42
obj = MyClass()
# 'value'という属性がobjに存在するかどうかをチェック
print(hasattr(obj, 'value')) # 出力: True
# 'nonexistent'という属性がobjに存在するかどうかをチェック
print(hasattr(obj, 'nonexistent')) # 出力: False
クラスに__call__メソッドを定義すると、そのクラスのインスタンスを関数のように呼び出すことができるようになります。これは「呼び出し可能オブジェクト」を作成する方法の1つ
pythonCopyclass Greeter:
def __init__(self, greeting):
self.greeting = greeting
def __call__(self, name):
return f"{self.greeting}, {name}!"
# インスタンスを作成
hello_greeter = Greeter("Hello")
# インスタンスを関数のように呼び出す
result = hello_greeter("Alice")
print(result) # 出力: Hello, Alice!